Lee*_*sen 1 typescript typescript-generics
我想创建一个 TypeScript 函数,它将接受字符串或数字数组并返回连接的字符串或数字之和。
我的尝试如下所示:
function arrayCat<T extends number | string>(n: Array<T>): string {
if (n.length > 0) {
if (typeof n[0] === 'string') {
return n.join(', ');
} else if (typeof n[0] === 'number') {
const v: Array<any> = n;
const sum: number = v.reduce((prev: number, curr: number)=> {
return prev + curr;
});
return sum.toString();
}
}
return '';
}
console.log(arrayCat([1, 2])); // Outputs: 3
console.log(arrayCat(['fish', 'cow'])); // Outputs: fish, cow
Run Code Online (Sandbox Code Playgroud)
但回归 TypeScript 似乎const v: Array<any> = n;
违背了 TypeScript 的初衷。
有一个更好的方法吗?
T extends number | string
不T
坚持number
或string
。这意味着Array<T>
可能同时包含数字和字符串。
当前的代码愉快地接受 [1, 2, 'fish', 'cow']
输入并产生意想不到的结果。
通过将函数签名更改为:
function arrayCat<T extends number[] | string[]>(n: T): string
Run Code Online (Sandbox Code Playgroud)
在这种情况下甚至不需要通用的。也可以写成:
function arrayCat(n: number[] | string[]): string
Run Code Online (Sandbox Code Playgroud)
代码的其余部分看起来不错,但在运行时不能保证输入数组的所有项目与第一项的类型相同。
我重构了代码以一次处理一种情况并验证输入数组的所有项目:
function arrayCat(n: number[] | string[]): string {
if (n.length === 0) {
return '';
}
if (isStringArray(n)) {
return n.join(', ');
}
if (isNumberArray(n)) {
return n.reduce((acc, curr) => acc + curr).toString();
}
// Here `n` contains values of more than one type or even of other types (not strings or numbers)
throw new Error(`Unexpected input: ${n}`);
}
//
// Type guards
function isStringArray(n: (string | number)[]): n is string[] {
return n.every((i) => typeof i === 'string');
}
function isNumberArray(n: (string | number)[]): n is number[] {
return n.every((i) => typeof i === 'number');
}
Run Code Online (Sandbox Code Playgroud)
网上查一下。
归档时间: |
|
查看次数: |
606 次 |
最近记录: |