简体   繁体   English

Flowtype扩展对象类型

[英]Flowtype extend object type

As JavaScript developer I'm new to type checking and I struggle to understand why this simple code is not working: 作为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); 

What I'm trying to achieve here is to have a method that accepts interface. 我在这里想要实现的是拥有一个接受接口的方法。 This however gives me error: Cannot call 'printAnimal' with 'buddy' bound to 'animal' because string literal 'dog' [1] is incompatible with string literal 'cat' [2] in property 'type'. 然而,这给了我错误: Cannot call 'printAnimal' with 'buddy' bound to 'animal' because string literal 'dog' [1] is incompatible with string literal 'cat' [2] in property 'type'. .

What I tried: 我尝试了什么:

  1. interface Animal { // ...} - does not work. interface Animal { // ...} - 不起作用。
  2. Remove typing from buddy - it work's but I'm not satisfied. buddy删除打字 - 它有效,但我不满意。 Sometimes I do want to have more strict type (so I know I'm dealing with dog not cat) but still use general method that accept any animal. 有时我确实想要更严格的类型(所以我知道我正在处理狗而不是猫),但仍然使用接受任何动物的一般方法。
  3. I tried changing type: 'dog' | 'cat' 我尝试改变type: 'dog' | 'cat' type: 'dog' | 'cat' to type: string - does not work. type: string type: 'dog' | 'cat' type: string - 不起作用。 I would expect 'dog' string is subtype of general string type but it's not. 我希望'dog'字符串是一般string类型的子类型,但事实并非如此。 On the other hand even if it works it wouldn't be enough - sometimes I know that my app accepts only dogs and cats not any other animals. 另一方面,即使它工作也是不够的 - 有时我知道我的应用只接受狗和猫而不是任何其他动物。

Thanks for reading and I hope I can get some help from you guys! 感谢阅读,我希望我能得到你们的帮助! Here's live version: Try Flow - live example 这是现场版: 尝试Flow - 实例

You have to make the Animal type an interface since it's describing your types implementations as a "parent". 您必须将Animal类型作为接口,因为它将您的类型实现描述为“父”。 And it would make sense if you enforce it by extending your Dog type via a union since that's the point of using typings to reach a stronger type-checking. 如果你通过联合扩展你的Dog类型来执行它是有意义的,因为这是使用typings来达到更强的类型检查的关键。

This can be written like this: 这可以这样写:

 /* @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); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM