Momentjs和Flow类型

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

我正在尝试学习如何使用流程,但我遇到了一条对我没用的错误消息。

这是我的代码:

import moment from "moment-timezone";
import type MomentType from "moment-timezone";

type filtersType = {
  page?: number,
  ccaa?: string,
  province?: string,
  date_from?: MomentType,
  date_to?: MomentType,
  distance_from?: number,
  distance_to?: number,
  category?: Array<string>,
};

const _parseValue = (value: mixed): string => {
  if (Array.isArray(value)) return value.join(",");
  else if (moment.isMoment(value)) return value.toISOString();
  else if (typeof value === "number") return value.toString();
  else if (typeof value === "string") return value;
  throw new Error("Filter value type is not valid!!");
};

const _generateQueryItem = (key: string, value: mixed): string => {
  return `${key}=${_parseValue(value)}`;
};

const _generateQuery = (filters: filtersType): string => {
  return Object.entries(filters)
    .map(([key, value]) => _generateQueryItem(key, value))
    .join("&");
};

它一直在抱怨这个,在第33行:

Cannot call value.toISOString because property toISOString is missing in mixed [1].                

 [1] 30│ const _parseValue = (value: mixed): string => {
     31│   console.log(moment.isDate(value));
     32│   if (Array.isArray(value)) return value.join(",");
     33│   else if (moment.isMoment(value)) return value.toISOString();                            
     34│   else if (typeof value === "number") return value.toString();                            
     35│   else if (typeof value === "string") return value;
     36│   throw new Error("Filter value type is not valid!!");                                    

我总是认为混合类型包含所有内容所以,它不应该抱怨任何方法丢失,我不确定最新情况,我试图将args类型更改为:

const _parseValue = (value: mixed | MomentType): string => {

和:

const _generateQueryItem = (key: string, value: mixed | MomentType): string => {

但我仍然得到同样的错误。

我需要一种方法让流知道valuetoISOString方法,但我今天用完了想法。我怎么做?

(我已经安装了带有流式btw的力矩类型)

javascript momentjs flowtype
1个回答
1
投票

啊,type refinement

所以你正试图改进value的类型。你这样做:

if (typeof value === "number") return value.toString();

检查value是否为数字。 Flow了解这一点,并将value细化为一个数字,以便您可以在其上调用toString

你这样做:

if (Array.isArray(value)) return value.join(",");

检查value是否为数组。 Flow了解这一点,并将value精炼为数组,因此您可以在其上调用join

你这样做:

if (moment.isMoment(value)) return value.toISOString();

检查value是否是一个时刻对象的实例。 Flow不理解这是一个改进。因此,您的类型没有被细化,因此当您尝试调用toISOString时,流程会告诉您mixed上不存在您的方法。

Flow仅支持一组小但功能强大的细化操作。它不知道isMoment甚至打算作为一个改进。流可以从mixed改进的唯一值是非常简单的旧数据值,数字,字符串,数组,对象,不可能从mixedMomentType进行优化。

首先,让我们停止依赖mixed。如果您只能接收一小部分类型作为可解析值,那么union将更好地为您服务,并且它将明确添加MomentType作为细化的可能性:

type Parseable = number | string | string[] | MomentType;

然后是我们对瞬间对象进行细化的问题。好吧,我们有两种可能性。如果我们真的只关心这些类型,意味着我们完全相信这些是我们将获得的唯一事物,那么我们甚至不必明确地改进到一个时刻对象:

const _parseValue = (value: Parseable): string => {
  if (Array.isArray(value)) return value.join(",");
  else if (typeof value === "number") return value.toString();
  else if (typeof value === "string") return value;

  return value.toISOString(); // by process of elimination, this is a moment
};

Flow很聪明,知道我们已经处理了所有其他情况,所以如果我们到达函数的末尾,那么通过消除value的过程必须是一个时刻。

那么,我们应该依赖这种行为吗?这得看情况。来自不可靠API的任意数据是否会被传递到_parseValue?或者来自流式代码库中可靠位置的良好类型的数据?如果我们不需要过多担心虚假数据,那么肯定要依赖于消除过程。否则,我们应该抓住你原来的错误案例。但这意味着我们必须明确改进我们的时刻类型:

const _parseValue = (value: Parseable): string => {
  if (Array.isArray(value)) return value.join(",");
  else if (typeof value === "number") return value.toString();
  else if (typeof value === "string") return value;
  // let's be extra careful
  else if (typeof value === 'object' && value.isMoment && value.toISOString) return value.toISOString();
  throw new Error("Filter value type is not valid!!");
};

Flow会接受我们的检查typeof value === 'object'足以区分valueParseable中的其他条目并确保它是MomentType,但由于我们的数据源可能是可疑的,我们还要检查value.isMoment(流量中定义的所有时刻对象的属性)暂时的libdef)。这应该超出合理怀疑,这实际上是一个时刻的对象。一种策略是只是将我们得到的任何对象鸭子打包成value.toISOString并继续调用它。

© www.soinside.com 2019 - 2024. All rights reserved.