Подобные вещи трудно описать с помощью Flow. Вы можете typecheck код, который использует эту функцию, но typechecking внутри функции будет трудно / неполным (из того, что я знаю). Один из способов кода typecheck, который использует , заключается в том, чтобы объявить гипотетическую функцию, которая делает то, что вы хотите, а затем использовать тип этой функции:
( Попробовать )
type Data = Num | Str;
type Num = {n: number};
type Str = {s: string};
function printNum({n}: $ReadOnly) {
console.log(n);
}
function printStr({s}: $ReadOnly) {
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 для элементов dom .
В приведенных выше примерах , Я решил утвердить тип объекта либо Str
, либо Num
. Я делаю это, чтобы мы могли сохранить некоторый уровень безопасности типа (например, если тип Str
или Num
изменяется в будущем), так как any
подавляет возможные проблемы, когда мы больше не возвращаем одну из этих вещей. Если вас это не волнует, вы можете упростить приведение к ({...contents...}: any)