【发布时间】:2020-09-13 20:24:59
【问题描述】:
下面是一些示例代码。 TypeScript 将validStudents 的类型推断为Students[]。任何阅读代码的人都应该清楚,因为所有无效记录都被过滤掉了,所以validStudents 可以安全地被认为具有ValidStudents[] 的类型。
interface Student {
name: string;
isValid: boolean;
}
type ValidStudent = Student & { isValid: true };
const students: Student[] = [
{
name: 'Jane Doe',
isValid: true,
},
{
name: "Robert'); DROP TABLE Students;--",
isValid: false,
}
];
const validStudents = students.filter(student => student.isValid);
function foo(students: ValidStudent[]) {
console.log(students);
}
// the next line throws compile-time errors:
// Argument of type 'Student[]' is not assignable to parameter of type 'ValidStudent[]'.
// Type 'Student' is not assignable to type 'ValidStudent'.
// Type 'Student' is not assignable to type '{ isValid: true; }'.
// Types of property 'isValid' are incompatible.
// Type 'boolean' is not assignable to type 'true'.ts(2345)
foo(validStudents);
可以通过添加类型断言来使这段代码工作:
const validStudents = students.filter(student => student.isValid) as ValidStudent[];
...但感觉有点hacky。 (或者也许我只是比我自己更信任编译器!)
有没有更好的方法来处理这个问题?
【问题讨论】:
-
它看起来有点难看,但我认为你正在做的是正确的做法。
-
为什么 TS 能够推断出这个?它只知道您在数组上调用
.filter,您也可以指定student => student.name.startsWith("A")作为过滤条件。或者其他任何不会改变数组组成的东西,因此它不能真正缩小类型。此外,如果您过滤一个空数组,您的有效性过滤器 still 会生成一个无效学生数组。以及一组有效学生。