本系列作为《TypeScript 入门实战笔记》课程(见拉勾教育)的补丁,随时更新。
类型守卫的改善:别名条件表达式和判别式的控制流分析
原文:Control flow analysis of aliased conditional expressions and discriminants #44730
这是 TypeScript 大佬 ahejlsberg 新近提的一个 PR,意味着不久的将来,大概率这个 feat 将在新版本里出现。
// 援引自官方示例
function f7(x: string | number | boolean) {
const isString = typeof x === "string";
const isNumber = typeof x === "number";
const isStringOrNumber = isString || isNumber;
if (isStringOrNumber) {
x; // C1 string | number
}
else {
x; // C2 boolean
}
}
复制代码
如以上示例所示,在目前的正式版本里(4.2.*),注释 C1、C2 处,变量 x 的类型并不会缩小成响应的 string | number 和 boolean,这也是被广泛吐槽的。
当然 C1、C2 处类型缩小是符合我们预期(合理)的,但这就需要 TypeScript 引擎做额外的代码分析(计算量、复杂度、成本)。所以大佬的这个 PR 里解决并仅解决了分析成本不那么高的场景,比如上边示例里的 const,以及直接和间接混合的条件表达式。
// 援引自官方表达式
function f8(value: number | undefined) : number {
const isNumber = typeof value == "number";
if (isNumber && value > 0) {
return value * 10;
}
return 0;
}
复制代码
但对于 let 或者其他比较复杂(难以追踪、分析类型条件,包括需要计算才能获得类型的)的情况,则无法做到类型缩小。
// 援引自官方示例
function f5(x: unknown) {
let isString = typeof x === 'string';
if (isString) {
x.length; // Error, no narrowing because isString isn't 'const'
}
}
type Data = { kind: 'str', payload: string } | { kind: 'num', payload: number };
function foo({ kind, payload }: Data) {
if (kind === 'str') {
payload.length; // Error, payload not narrowed to string
}
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END