【问题标题】:Safely casting mixed type into appropiate type with flow安全地将混合型铸造成合适的流动型
【发布时间】:2019-07-21 11:13:21
【问题描述】:

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

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) 无法调用 FlowTest.convertSingleSafe 并将 d 绑定到 data,因为在索引器属性中:混合 [1] 与数字 [2] 不兼容。或者混合[1]与布尔[3]不兼容。或者混合[1]与字符串[4]不兼容。

那么(如何)我可以不经过any casts 做到这一点?

【问题讨论】:

    标签: javascript type-conversion flowtype


    【解决方案1】:

    关于type refinement in flow,你必须了解的是它不是很聪明。 Flow 基本上是在寻找像typeof &lt;something&gt; === '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}`, '');
    }
    

    还有here's the generic version

    【讨论】:

    • 如果您尝试分配给类型化的 var,则不起作用,例如 const a: number = convertSingleSafe({ a: 1 }, 'a', 'number');
    • 在答案中添加了通用版本,因为链接太长,无法发表评论。你会想要这样的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-03
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    相关资源
    最近更新 更多