给定:
function sorter<T extends string | number> () {
const icf = new Intl.Collator().compare
return (a: T, b: T) => typeof a === 'number' ? a - b : icf(a, b)
}
我们收到 Typescript 类型错误:
我们知道,如果a
是一个数字,那么b
也将是一个数字,同样,如果a
是一个字符串,那么 >b
也将是一个字符串。调用排序器的函数不知道此信息,即仅在调用返回的函数时才知道。按照设计,我们从不期望得到异构的元素。
有哪些选项可以正确断言这些类型?
最佳答案
你可以这样做:
type T = number | string;
function numSorter(a: number, b: number){
return a - b;
}
function stringSorter(a: string, b: string, locale: string) {
const icf = new Intl.Collator(locale).compare;
return icf(a,b)
}
function picker(a: T, b: T, locale: string) {
if (typeof a === 'number' && typeof b === 'number') {
return numSorter(a,b);
} else if (typeof a === 'string' && typeof b === 'string') {
return stringSorter(a,b, locale);
} else {
throw Error("incompatible types");
}
}
function sorter(locale: string) {
return (a:T, b:T) => picker(a,b,locale);
}
const mySorter = sorter("US");
console.log(mySorter(1,2)); //both numbers, so ok
console.log(mySorter("world","hello")); // both strings, so ok
console.log(mySorter(1,"hello")); // incompatible types
输出如下:
我可能是错的,但我认为这种方法违背了静态类型检查的目的。通用引用仍然需要有具体的实现。
在这种情况下,对于不同类型的number
和string
,您执行的操作是不同的,因此不存在重叠。通用方法对于在功能上确实有一些重叠的对象可能很有用,例如它们都有一个通用方法,例如如果您想要一个辅助方法来查找数组的长度(如 docs 中所示):
function loggingIdentity<Type>(arg: Array<Type>): Array<Type> {
console.log(arg.length); // Array has a .length, so no more error
return arg;
}
这个通用函数适用于任何类型的任何数组,因为任何数组都具有 length
属性。
总的来说,我认为它对于这种情况没有用,我认为从一开始就有具体的实现,并在需要时调用正确的排序函数可能会更好。说实话,泛型有点让人头疼,尤其是在 TypeScript 中。
关于typescript - 强制 Typescript 通用参数(a : T, B: T)为相同类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72320085/