[英]TypeScript: Difference Generic Constraints VS Parameter Type
我不明白通用約束和普通參數類型之間的區別。 在第一種情況下,我確實明白我不能調用 si.g() 因為我嚴格地將 si 鍵入為 SomeInterface 類型。 但是,在第二個示例中, S 擴展了 SomeInterface ,根據我的解釋,擴展意味着它需要具有 f() 但可以包含更多屬性。 但錯誤是一樣的。 為什么?
interface SomeInterface {
f();
}
function test1(si: SomeInterface) {
si.f()
// si.g() -> Property 'g' does not exist on type 'SomeInterface'
}
function test2<S extends SomeInterface>(si: S) {
si.f()
// si.g() -> Property 'g' does not exist on type 'SomeInterface'
}
Typescript 需要檢查您傳遞的類型是否包含函數g
。 所以你需要做這樣的事情:
interface ExtendedInterface extends SomeInterface {
g();
}
...
function test2<E extends ExtendedInterface>(ei: E) {
si.f()
si.g()
}
當然,你也可以這樣做:
function test3(ei: ExtendedInterface) {
ei.g();
ei.f();
}
這在功能上與帶有泛型的版本相同。
那么有什么區別呢? 這里沒有什么,但是泛型以更復雜的代碼為代價為您提供了更多的功能。 例如,泛型允許您聲明受另一個類型參數約束的類型參數。
...擴展意味着它需要有 f() 但可以包含更多屬性。 但錯誤是一樣的。 為什么?
因為它可能有也可能沒有更多的屬性,如果有,它們可能有任何名稱或任何類型。 TypeScript 不知道這些屬性是什么,所以在test2
,TypeScript 只知道si
是SomeInterface
。
您首先說您不了解類型參數( <S extends SomeInterface>
和si: S
)與僅將類型放在參數上( si: SomeInterface
)之間的si: SomeInterface
。 類型參數讓你做更多有趣的事情,比如:
function pluck<Type extends object, Key extends keyof Type>(array: Type[], key: Key) {
return array.map(element => element[key]);
}
const objects = [{a: 2, b: "s"}, {a: 3, b: "x"}];
const x = pluck(objects, "a"); // `x` is `number[]`
const y = pluck(objects, "b"); // `y` is `string[]`
我可能弄錯了,但我認為如果沒有類型參數(或類型斷言),您就無法做到這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.