Tom*_*mas 6 javascript typescript
这可能是一个重复的问题;但是我似乎找不到答案,所以如果已经有人回答了,请随时指出我的地方。
在使用泛型时,我发现 typescript 会根据我是否包装用作数组成员的泛型来推断不同的类型。例如,
// Set up
type Wrapped<I> = { _i: I };
// Not working example
function foo1<TInner extends unknown>(bar: Wrapped<TInner>[]) {
return bar;
}
const a = foo1([{ _i: 5 }, { _i: "six" }]); // TInner = number, compiler complains about second array member despite the fact that it's inferring it
// Working example
function foo2<TInner extends Wrapped<unknown>>(bar: TInner[]) {
return bar;
}
const b = foo2([{ _i: 5 }, { _i: "six" }]); // TInner = Wrapped<number> | Wrapped<string>
Run Code Online (Sandbox Code Playgroud)
为什么会这样?文档中是否有我遗漏的内容?更笼统地说,有人能指出我对打字稿如何推断泛型的一个很好的解释吗?
小智 0
仔细看看代码的编写方式。
// Slightly edited given example
type Wrapped<I> = { _i: I };
function foo<T extends unknown>(baz: Wrapped<T>[]) {}
foo1([ { _i: 5 }, { _i: "six" } ]);
function bar<T extends Wrapped<unknown>>(baz: T[]) {}
foo2([ { _i: 5 }, { _i: "six" } ]);
Run Code Online (Sandbox Code Playgroud)
定义了wayfoo的通用参数,T extends unknown,意味着T可以是任何东西,用 表示unknown,但它是1件事。
实际函数的参数是Wrapped<T>[];将其分解,foo接受一个数组Wrapped<T>,这意味着它接受一个对象列表Wrapped,但每个对象都必须具有相同的类型,因此它可以接受[ { _i: 1 }, { _i: 2 }, { _i: 3 } ],或[ { _i: 'a' }, { _i: 'b' }, { _i: 'c' } ],但它不能创建一个联合/元组作为它的输出,所以像[ { _i: 'a' }, { _i: 2 }, { _i: Symbol(NaN) } ]会失败,因为这种类型实际上是Wrapped<string | number | symbol>[],而前两种类型分别是Wrapped<number>[]、 和Wrapped<string>[]。
bar另一方面,定义为<T extends Wrapped<unknown>>。在这种情况下,T就是 类型的对象Wrapped,不关心它的类型参数是什么,只要它具有对象的一般形状即可Wrapped。在这里,它可以采用对象数组Wrapped,无论它们是否都属于相同类型。
总结一下,foo接受相同类型的连续数组,而bar接受任何对象的数组Wrapped。
| 归档时间: |
|
| 查看次数: |
67 次 |
| 最近记录: |