我有此代码:
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]
。
如何使用可以包含几种(不同的,不可统一的)类型的变量?我必须使用两个单独的变量,每种类型一个吗?
答案 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中看到这种使用多功能声明的模式。
在以上示例中,我选择将对象的类型声明为Str
或Num
。我这样做是为了保留某种级别的类型安全性(例如,Str
或Num
的类型将来会更改),因为any
抑制了我们不再可能遇到的问题返回其中之一。如果您不在乎,可以将类型转换简化为({...contents...}: any)