流错误:...中缺少属性,但存在于

时间:2018-07-13 07:39:15

标签: javascript flowtype

我有此代码:

type Data = Num | Str;
type Num = {n: number};
type Str = {s: string};

function printNum({n}: Num) {
  console.log(n);
}

function printStr({s}: Str) {
  console.log(s);
}

function loadData(t: 'Num' | 'Str'): Data {
  if (t === 'Num') {
      return {n: 123};
  } else {
      return {s: 'abc'};
  }
}

const data = loadData('Num');

printNum(data);

这不会进行类型检查:Cannot call 'printNum' with 'data' bound to the first parameter because property 'n' is missing in 'Str' [1] but exists in 'Num' [2]

如何使用可以包含几种(不同的,不可统一的)类型的变量?我必须使用两个单独的变量,每种类型一个吗?

https://flow.org/try/#0C4TwDgpgBAIghsOUC8UByBXAtlAPlAZWACcBuAKFEnWxSgG8A7ALikewCMJiBfCq6EWJ16AZ1aiSAS0YBzPuXIAzDIwDGwKQHtGUMMRnBMWABRMerYwEoG5KFDU7RWgDYQAdC62yTjKxR5FFXVNHT0DRmAhM1ELQhIbejsHJ1cPLx9Rf3JA5VUNbV0vOAATeEQTYFYAcmNqvChqoWqrVnKkJPspJShKlGRUWuwW23sxqGIIYAxiXSZWAEYAJgBmBXseKAgXUWhO8YmpmbnxRrgONWr1qEDcx0ZJKBKEJFRispeTIawWinJ9QzGEzPRDZIA

1 个答案:

答案 0 :(得分:0)

用Flow很难检查这种事情。您可以对使用该函数的代码进行类型检查,但根据我所知,该函数内部的类型检查将很困难/不完整。类型检查使用函数的代码的一种方法是声明一个假设的函数,该函数执行所需的操作,然后使用该函数的类型:

Try

type Data = Num | Str;
type Num = {n: number};
type Str = {s: string};

function printNum({n}: $ReadOnly<Num>) {
  console.log(n);
}

function printStr({s}: $ReadOnly<Str>) {
  console.log(s);
}

declare function idealFunc(t: 'Str'): Str
declare function idealFunc(t: 'Num'): Num

const loadData: typeof idealFunc = (t) => {
  if (t === 'Num') {
      return (({n: 123}: Num): any); // Suppress warnings while still ensuring we return a Num
  } else if (t === 'Str') {
      return (({s: 'abc'}: Str): any); // Suppress warnings while still ensuring we return a Str
  }
  throw new Error("Invalid type")
}

const data = loadData('Num');

printNum(data); // look ma, no error

您可以在libdefs for dom elements中看到这种使用多功能声明的模式。

在以上示例中,我选择将对象的类型声明为StrNum。我这样做是为了保留某种级别的类型安全性(例如,StrNum的类型将来会更改),因为any抑制了我们不再可能遇到的问题返回其中之一。如果您不在乎,可以将类型转换简化为({...contents...}: any)