kim*_*gro 3 typescript generic-type-parameters
下面的两个泛型类型参数在功能上有什么区别吗?
function funcA<T>() { }
function funcB<T extends {}>() {}
Run Code Online (Sandbox Code Playgroud)
我已经看到它们都使用过并且对差异感到困惑?
注意:我假设您使用的是 TypeScript 3.5 或更高版本;在 TypeScript 3.5 中进行了更改,以便泛型类型参数被隐式约束unknown而不是空对象 type{},以及有关funcA()和funcB()更改之间差异的一些小细节。我不想通过谈论过去在 TS3.4 及更低版本中的情况来发表更长的文章。
如果您没有通过 显式约束泛型类型参数extends XXX,那么它将被隐式约束unknown,即所有类型都可以分配到的“顶级类型”。因此,实际上这意味着TinfuncA<T>()绝对可以是您想要的任何类型。
在另一方面,空的对象类型{},是一种到几乎所有类型的分配,除了为null和undefined,当你启用了--strictNullChecks编译器选项(你应该)。甚至像string和这样的原始类型也number可以分配给{}.
所以比较:
function funcA<T>() { }
funcA<undefined>(); // okay
funcA<null>(); // okay
funcA<string>(); // okay
funcA<{ a: string }>(); // okay
Run Code Online (Sandbox Code Playgroud)
和
function funcB<T extends {}>() { }
funcB<undefined>(); // error
funcB<null>(); // error
funcB<string>(); // okay
funcB<{ a: string }>(); // okay
Run Code Online (Sandbox Code Playgroud)
唯一的区别是T extends {}禁止null和undefined。
{}所谓的“对象”类型会接受像string和这样的原语,这可能有点令人困惑number。它有助于觉得这样花括号包围的类型,如{}和{a: string}以及所有interface类型的不一定为“真正的”对象类型,但类型,你可以索引到他们,如果他们没有得到运行时错误对象的值。除了null和之外的原语undefined是“类对象”,因为您可以将它们视为用它们的对象等价物包裹:
const s: string = "";
s.toUpperCase(); // okay
Run Code Online (Sandbox Code Playgroud)
因此,即使像这样string的原语也可以分配给花括号包围的类型,只要这些类型的成员匹配:
const x: { length: number } = s; // okay
Run Code Online (Sandbox Code Playgroud)
如果你真的需要表达一个只接受“真”的类型,即非原始对象,你可以使用object:
const y: object & { length: number } = s; // error
const z: object & { length: number } = { length: 10 }; // okay
Run Code Online (Sandbox Code Playgroud)
但我(认真地)离题了。
好的,希望有帮助;祝你好运!
| 归档时间: |
|
| 查看次数: |
3165 次 |
| 最近记录: |