javascript - Flowtype 扩展对象类型
问题描述
作为 JavaScript 开发人员,我是类型检查的新手,我很难理解为什么这个简单的代码不起作用:
type Animal = {
id: number,
name: string,
type: 'dog' | 'cat'
};
type Dog = {
id: number,
name: string,
type: 'dog',
color: string
};
function printAnimal(animal: Animal): string {
return `${animal.type}: ${animal.name}`;
}
const buddy: Dog = {
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
}
printAnimal(buddy);
我在这里想要实现的是有一个接受接口的方法。然而,这给了我错误:Cannot call 'printAnimal' with 'buddy' bound to 'animal' because string literal 'dog' [1] is incompatible with string literal 'cat' [2] in property 'type'.
。
我尝试了什么:
interface Animal { // ...}
- 不工作。- 删除输入
buddy
- 它有效,但我不满意。有时我确实想要更严格的类型(所以我知道我在处理狗而不是猫)但仍然使用接受任何动物的一般方法。 - 我尝试更改
type: 'dog' | 'cat'
为type: string
- 不起作用。我希望'dog'
字符串是通用string
类型的子类型,但事实并非如此。另一方面,即使它有效也不够——有时我知道我的应用程序只接受狗和猫,而不接受任何其他动物。
感谢阅读,希望能得到大家的帮助!这是现场版本:Try Flow - 现场示例
解决方案
您必须将Animal
类型设置为接口,因为它将您的类型实现描述为“父级”。如果您通过联合Dog
扩展您的类型来强制执行它,那将是有意义的,因为这是使用类型来实现更强大的类型检查的关键。
这可以这样写:
/* @flow */
interface Animal {
id: number,
name: string,
type: 'dog' | 'cat'
};
type Dog = Animal & {
type: 'dog',
color: string
};
function printAnimal(animal: Animal): string {
return `${animal.type}: ${animal.name}`;
}
const buddy: Dog = {
id: 1,
name: 'Buddy',
type: 'dog',
color: 'black'
}
printAnimal(buddy);
推荐阅读
- javascript - 在 Overleaf 上使用 javascript 发送密钥
- terraform - 如何将敏感输出变量的值分配给环境变量?
- sublimetext3 - 在 Sublime Text 中更改用于列选择的鼠标按钮和修饰键
- react-native - react-native-print 使用 html 在 react-native-print 中打印带有数据集的文档
- python - 使用python的socket库时用户输入错误
- python - 分段错误:升级到 OS Big Sur 后出现 11 python
- python - 在 NetworkX 图中添加具有属性的节点
- python - 在另一个 csv 文件中查找一个数据并使用查找值打印第一个数据值
- javascript - 按钮单击功能不适用于 HTML 变量 | 如何解决?
- python - FileNotFoundError: [Errno 2] No such file or directory: 'data/obj' in Python