Flowtype扩展对象类型

Ern*_*cki 5 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);
Run Code Online (Sandbox Code Playgroud)

我在这里想要实现的是拥有一个接受接口的方法.然而这给了我错误:Cannot call 'printAnimal' with 'buddy' bound to 'animal' because string literal 'dog' [1] is incompatible with string literal 'cat' [2] in property 'type'..

我尝试了什么:

  1. interface Animal { // ...} - 不起作用.
  2. 删除键入buddy- 它的工作,但我不满意.有时我确实想要更严格的类型(所以我知道我正在处理狗而不是猫),但仍然使用接受任何动物的一般方法.
  3. 我试过换type: 'dog' | 'cat'type: string- 不行.我希望'dog'string是一般string类型的子类型,但事实并非如此.另一方面,即使它工作也是不够的 - 有时我知道我的应用程序只接受狗和猫而不是任何其他动物.

感谢阅读,我希望我能得到你们的帮助!这是现场版:尝试Flow - 实例

Iva*_*ele 1

您必须使该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);
Run Code Online (Sandbox Code Playgroud)