说我返回了一些随机对象数据。现在,我希望验证并将其转换为适当的类型,以在我的其余应用程序中使用。为此,我编写了以下实用函数。
static convertSingleSafe<T: (number | boolean | string | void)>(
data: {[string]: mixed},
name: string,
type: 'number' | 'boolean' | 'string' | 'object' | 'undefined'): T {
if (typeof data[name] === type ) {
return data[name]
} else {
throw new KeyError(`Badly formated value ${name}`, '')
}
}
将被称为:
const data: {[string]: mixed} = {val: 10, otherdata: 'test'};
//data would come from IE JSON.parse() of a request to server.
const val: number = convertSingleSafe<number>(data, 'val', 'number');
const msg: string = convertSingleSafe<string>(data, 'otherdata', 'string);
但是,问题在于流程似乎无法理解convertSingleSafe
函数中的断言。在return data[name]
上显示以下错误:
错误:(82,20)无法返回
data[name]
,因为:混合的[1]与数字[2]不兼容。或[1]与布尔[3]不兼容。或混合[1]与字符串[4]不兼容。
即使我已经明确测试了该特定值。
static convertSingleSafe<T: (number | boolean | string | void)>(
data: {[string]: T},
name: string,
type: 'number' | 'boolean' | 'string' | 'object' | 'undefined'): T
错误:(191,41)无法在绑定到{{1}的
FlowTest.convertSingleSafe
上调用d
,因为在索引器属性中:混合[1]与数字[2]不兼容。或[1]与布尔[3]不兼容。或混合[1]与字符串[4]不兼容。
那么(如何)可以执行此操作而无需进行data
强制转换?
答案 0 :(得分:0)
您对type refinement的使用流程了解到的是,它不是很聪明。 Flow基本上正在寻找typeof <something> === 'number'
之类的构造,就像想象它正在使用正则表达式来扫描您的代码(实际上并非如此)。 Here's可以满足我的要求的示例:
static convertSingleSafe(
data: {[string]: mixed},
name: string,
type: 'number' | 'boolean' | 'string' | 'object' | 'undefined'
): number | boolean | string | {} | void {
const subject = data[name];
if (type === 'number' && typeof subject === 'number') {
return subject;
}
if (type === 'boolean' && typeof subject === 'boolean') {
return subject;
}
if (type === 'string' && typeof subject === 'string') {
return subject;
}
if (type === 'undefined' && typeof subject === 'undefined') {
return subject;
}
if (type === 'object' && subject && typeof subject === 'object') {
return subject;
}
throw new KeyError(`Badly formated value ${name}`, '');
}