繁体   English   中英

安全地将混合型浇铸成合适的型

[英]Safely casting mixed type into appropiate type with flow

说我返回了一些随机对象数据。 现在,我希望验证并将其转换为适当的类型,以在我的其余应用程序中使用。 为此,我编写了以下实用函数。

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 

错误:( FlowTest.convertSingleSafe )无法将d绑定到data调用FlowTest.convertSingleSafe ,因为在索引器属性中:混合[1]与数字[2]不兼容。 或[1]与布尔[3]不兼容。 或混合[1]与字符串[4]不兼容。

所以(如何)我可以这样做,而无需进行any强制转换?

关于流中的类型优化 ,您必须了解的是它不是很聪明。 Flow基本上在寻找类似typeof <something> === 'number'的构造,就像想象中的那样,它正在使用正则表达式来扫描代码(实际上并非如此)。 这是一个可以满足我的要求的示例:

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}`, '');
}

是通用版本

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM