解构赋值和休息参数在现在的代码库中是非常棒的,也是典型的。但在TypeScript中,是否有可能对这些进行强类型化?让我们来看看。
TypeScript有图元
在我们弄清楚如何强类型的休息参数之前,让我们先了解图元。一个元组可以被认为是一个有固定数量元素的数组。它们对于小而明显的数据结构是很好的。例如,useState React钩子返回一个tuple:
const [state, setState] = useState(initialState);
TypeScript让我们在类型注解中定义元组,在方括号中指定每个元素的类型。比如说:
const tomScore: [string, number]: ["Tom", 70];
开放式图元
图元与休息参数有什么关系?好吧,我们最终会到达那里。
TypeScript让我们拥有图元,在图元中我们可以有不同数量的末端元素,就像下面这样:
["Tom", 70][("Jane", 70, 60)][("Fred", 70, 60, 80)];
我们可以指定上述例子的类型为[string, ...number[]] 。
强类型化的休息参数
我想知道我们是否可以使用一个开放式元组来强类型的休息参数?让我们试着为下面的函数中的scores 参数这样做:
function logScores(firstName, ...scores) {
console.log(firstName, scores);
}
logScores("Ben", 50, 75, 85); // outputs Ben and [50, 75, 85]
让我们来试试这个:
function logScores(firstName: string, ...scores: [...number[]]) {
console.log(firstName, scores);
}
如果我们想一想,[...number[]] 就只是number[] 。所以,这可以简化为:
function logScores(firstName: string, ...scores: number[]) {
console.log(firstName, scores);
}
......而如果我们消耗这个函数:
logScores("Ben", 50, 75, 85); // okay
logScores("Mike", 90, 65, "65"); // Argument of type '"65"' is not assignable to parameter of type 'number'
很好--它成功了!
强类型的非结构化赋值
在非结构化对象变量上指定类型,也许不是你最初所期望的那样实现的。下面并没有为firstName 和score 指定类型注释:
const fred = { firstName: "Fred", score: 50 };
const { firstName: string, score: number } = fred;
相反,它为非结构化变量指定了名称:
console.log(firstName); // cannot find name 'firstName'
console.log(score); // cannot find name 'score'
console.log(string); // "Fred"
console.log(number); // 50
我们在去结构化对象后面指定类型注解,如下所示:
const { firstName, score }: { firstName: string; score: number } = fred;
console.log(firstName); // "Fred"
console.log(score); // 50
如果我们正在对一个元组进行解构,我们在解构的元组后面指定元组的类型:
const tomScore: [string, number]: ["Tom", 70];
const [firstName, score]: [string, number] = tomScore;
console.log(firstName); // "Tom"
console.log(score); // 70
我们可以在一个开放元组上指定一个类型,如下所示:
const tomScores: [string, ...number[]] = ["Tom", 70, 60, 80];
const [firstName, ...scores]: [string, ...number[]] = tomScores;
console.log(firstName); // "Tom"
console.log(scores); // [70, 60, 80]
值得注意的是,通常TypeScript会巧妙地推断出去结构化元素的类型,但知道如何在不指定类型的边缘情况下指定类型注释是很好的。
总结
TypeScript图元是对小而明显的数据结构进行强类型化的一种方便方式。开放式图元可以用于强类型的休息参数。TypeScript通常会聪明地为我们推断出非结构化元素的类型,但当它不能这样做时,我们可以简单地在非结构化项目后面加上一个类型注释。