通过流动将混合型安全地浇铸成适当的类型

问题描述 投票:0回答:1

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

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]不兼容。或者mixed [1]与boolean [3]不兼容。或者混合[1]与字符串[4]不兼容。

即使我非常明确地测试该特定值。


The other option, to let the generic be part of the data type gives the following error:
static convertSingleSafe<T: (number | boolean | string | void)>(
        data: {[string]: T},
        name: string,
        type: 'number' | 'boolean' | 'string' | 'object' | 'undefined'): T

错误:(191,41)无法调用与FlowTest.convertSingleSafe绑定到ddata,因为在indexer属性中:mixed [1]与数字[2]不兼容。或者mixed [1]与boolean [3]不兼容。或者混合[1]与字符串[4]不兼容。

所以(怎么样)我可以这样做,而不通过any演员表?

javascript type-conversion flowtype
1个回答
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}`, '');
}
© www.soinside.com 2019 - 2024. All rights reserved.