首页 > 解决方案 > 如何使用 typeof 关键字缩小类型?

问题描述

interface Students {
    [key:string]: (Student | undefined);
}

interface Student {
    age: string;
}

function something (students:Students, student_name:string) {
    let student:Student;

    if (typeof students[student_name] !== 'undefined')
        student = students[student_name]; // Type 'Student | undefined' is not assignable to type 'Student'.
    else
        return;
}

我经常遇到这种情况。当然,我可以用作 Student。但是,我想知道是否有更好的方法。

标签: typescript

解决方案


通常 TypeScript 会使用控制流分析来自动缩小一个值的类型,一旦你检查了它。但是您遇到的问题是,这种缩小不会发生在括号样式的属性访问中(请参阅microsoft/TypeScript#10530),例如students[student_name]. 它适用于文字索引类型(参见microsoft/TypeScript#26424),例如students["Alice"], 等价于students.Alice... 但使其工作string显然会大大降低编译器性能。

这里的解决方法是只执行一次索引访问,并将结果分配给一个新变量。然后,当您检查该变量时,控制流分析应该根据需要缩小:

function something(students: Students, student_name: string) {      
  let student: Student;      
  const maybeStudent = students[student_name]; // Student | undefined
  if (typeof maybeStudent !== 'undefined')
    student = maybeStudent; // okay, maybeStudent narrowed to Student in check
  else
    return;
}

Playground 代码链接


推荐阅读