TypeScript `const` 断言
TypeScript const
断言
当对字面量使用 const
断言/const
assertions 时,
- 字面量中类型不会再宽泛,比如
hello
不再会认为是string
类型,就是hello
类型 - 对象属性变成
readonly
- 数组变成
readonly
的元组(tuple) 类型
示例:
// Type '"hello"'
let x = "hello" as const;
// Type 'readonly [10, 20]'
let y = [10, 20] as const;
// Type '{ readonly text: "hello" }'
let z = { text: "hello" } as const;
相对 const
声明的字面量具体有什么区别,考察如下代码:
function getShapes() {
const result = [
{ kind: "circle", radius: 100 },
{ kind: "square", sideLength: 50 },
];
return result;
}
此时如果我们观察上述函数的返回类型可得到:
({
kind: string;
radius: number;
sideLength?: undefined;
} | {
kind: string;
sideLength: number;
radius?: undefined;
})[]
即,函数返回的为一个 union 类型的数组,元素中都出现的 kind
字段没影响,而另外两个字段因为只分别在一个对象中出现过,所以会形成一个 undefined
类型。
这样严格模式 strict:true
下使用的时候就会报错:
let num=0;
for (const shape of getShapes()) {
if (shape.kind === "circle") {
// ❌Type 'number | undefined' is not assignable to type 'number'.
num = shape.radius
} else {
// ❌Type 'number | undefined' is not assignable to type 'number'.
num = shape.sideLength
}
}
如果改成 const
断言,返回的则是字面量原有未经过转换过的类型:
function getShapes() {
const result = [
{ kind: "circle", radius: 100 },
{ kind: "square", sideLength: 50 },
- ];
+ ] as const;
return result;
}
观察此时返回的类型为:
readonly [{
readonly kind: "circle";
readonly radius: 100;
}, {
readonly kind: "square";
readonly sideLength: 50;
}]
此时通过 shape.kind
进行类型区分后,原先两个对象就被成功分离开了,使用时自动提示也只会提供对应对象上有的字段:
for (const shape of getShapes()) {
if (shape.kind === "circle") {
// ✅
num = shape.radius
} else {
// ✅
num = shape.sideLength
}
}