这是一个代码示例:
declare function test_ok<T>(arr: T[]): T;
test_ok([1, 2, "hello"]); // OK
test_ok([[1], [2], ["hello"]]); // OK
// note the nested array signature
declare function test_err<T>(arr: T[][]): T;
test_err([[1], [2], ["hello"]]); // ERR type "string" is not assignable to type "number"
test_err<string | number>([[1], [2], ["hello"]]); // OK if generic is specified
Run Code Online (Sandbox Code Playgroud)
在一般情况下,当给定异构数组时,TypeScript能够推断出最佳的通用类型(基本并集)。但是,如果您尝试将泛型的作用域扩展到除简单数组(例如上面的嵌套数组)之外的任何范围,它就会放弃。我还发现其他情况(例如,泛型在函数的返回类型而不是整个函数之上的函数数组)。这是某种性能优化吗?
我要说的是,这更像是故意捕获错误而不是性能优化。当尝试推断T给定的一组应该是type的值时,T可以通过扩展T以适合所有值来始终成功,但是,当出现其中一个值输入错误的情况时,就不可能捕获合法错误。我认为,这是语言设计者的一种判断力,任何启发式方法都可能会产生一些误报和一些误报。
GitHub的问题,微软/打字稿#31617是一个类似的报告,其中一个用户希望string | number从两个参数,类型的一个推断string和其他类型的number。语言维护者之一的答复是:
这是一种有意的权衡,因此泛型可以在您希望多个对象属于同一类型的情况下捕获错误,这通常更为常见。
那么,该怎么办呢?显然,您可以手动指定T为string | number。否则,如果您希望函数是允许的并且从不抛出错误,则可以使T给定参数本身成为类型。与给定该类型的某个函数的值时相比,编译器在推断具有该类型的值的类型时要更加一致。因此,我的解决方法是使用数组:
declare function test_fixed<T extends any[][]>(arr: T): T[number][number];
const ret = test_fixed([[1], [2], ["hello"]]); // string | number
Run Code Online (Sandbox Code Playgroud)
在这种情况下,T被约束为双嵌套数组,而返回类型T[number][number]则是最里面的数组的元素类型(如果采用T,并在number索引处查找值,则将获得另一种数组类型...如果您查找的值是一个在number指数,你会得到最里面的元素类型... T[number][number]。)
好的,希望对您有所帮助。祝好运!
| 归档时间: |
|
| 查看次数: |
49 次 |
| 最近记录: |