作为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 - live example
答案 0 :(得分:1)
您必须使Animal
类型成为接口,因为它会将您的类型实现描述为“父项”。如果您通过通过 union 扩展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);