我经常看到这种业余的错误。像这样的接口定义经常出现在接口设计中:它本应使用限定允许值为一组预定义的常量,但实际上并没有做到。
const CAT = '喵';
const DOG = '汪汪';
const COW = '哞哞';
interface Animal {
name: string;
sound: typeof CAT | typeof DOG | typeof COW;
}
这根本行不通。这种限制会让一个完全无效的值通过。
const myAnimal: Animal = {
name: 'Fluffy',
sound: '乱七八糟的声音'
}
这是因为 typeof CAT
表示的是 CAT
常量的类型,其类型是字符串。同样地,typeof DOG
和 typeof COW
表示的也是字符串类型。如果这些常量中的任何一个不是字符串,那么 sound
就会接受其他类型的值。
解决方案是将常量定义为常量字面量。只需在它们定义后面添加 as const
。
例如,你可以这样定义一个常量字面量:example = "example" as const;
const CAT = '喵' as const; // meow
const DOG = '汪' as const; // woof
const COW = '哞' as const; // moo
interface Animal { // 动物接口定义
name: string; // 名称
sound: '喵' | '汪' | '哞'; // 声音
}
现在你告诉 Typescript,CAT
、DOG
和 COW
不再是简单的字符串,而是字符串字面量,因此,不仅它们的类型,它们的具体值也很重要。现在,Animal
类型只会接受 sound
的值为这些中的一个。