繁体   English   中英

TypeScript:差异通用约束 VS 参数类型

[英]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 只知道siSomeInterface

您首先说您不了解类型参数( <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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM