如何在TypeScript中处理ISO日期字符串?

siotufzp  于 2023-02-17  发布在  TypeScript
关注(0)|答案(4)|浏览(137)

我是打字新手,所以我想掌握它的窍门。
网络请求将返回一个JSON对象,其中包含一个ISO日期字符串格式的字段。

data : Data = {when: "2016-07-13T18:46:01.933Z"}

当我为这个接口创建类型签名时,有没有办法指定它实际上是一个ISO时间戳,或者我只需要使用字符串?

interface Data {
  when: string
}

我发现我可以使用一个类型别名,这在心理上有所帮助,但并不能真正验证ISO字符串。

type iso = string
interface Data {
  when: iso
}

同样,我很好奇是否有任何方法可以从这些typescript注解中生成js验证,这样我就可以验证端点接收到的信息,否则我输入的应用程序的其余部分就毫无价值了。
如果这是可能的,那么如果这个iso字符串可以被强制到一个实际的Date对象中,那就太酷了。
正如我所说的,我是 typescript 的新手,所以我不确定这是否超出了 typescript 应该做的事情的范围。

iecba09b

iecba09b1#

您可以使用Type Guard

import moment from 'moment'

export const isISO = (input: any): input is tISO =>
  moment(input, moment.ISO_8601, true).isValid()

然后,您可以使用中的任何自定义逻辑来处理任何错误的日期,例如:

const maybeISO = fetch('Maybe ISO')

if (isISO(maybeISO)) {
  // proceed
} else {
  // check other format?
  // log error?
}

干杯。

ruyhziif

ruyhziif2#

如果可以将此iso字符串强制转换为实际的Date对象,那就太酷了
不,这是不可能的。对于javascript来说,typescript的接口没有任何关系。(JS根本不为接口生成)。而且所有的类型检查都是在“编译”或“传输”时完成的,而不是在运行时。
可以做的是,在解析json时使用reviver函数。例如:

const datePattern = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/;
const json = '{"when": "2016-07-13T18:46:01.933Z"}';

const result = JSON.parse(json, (key: any, value: any) => {
    const isDate = typeof value === 'string' && datePattern.exec(value);
    return isDate? new Date(value) : value;
});

您还可以通过键来标识Date属性,如果它与日期模式不匹配,您可以抛出错误或执行任何您想要的操作。

1u4esq0p

1u4esq0p3#

试试这个:

// In TS, interfaces are "open" and can be extended
interface Date {
  /**
   * Give a more precise return type to the method `toISOString()`:
   * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
   */
  toISOString(): TDateISO;
}

type TYear         = `${number}${number}${number}${number}`;
type TMonth        = `${number}${number}`;
type TDay          = `${number}${number}`;
type THours        = `${number}${number}`;
type TMinutes      = `${number}${number}`;
type TSeconds      = `${number}${number}`;
type TMilliseconds = `${number}${number}${number}`;

/**
 * Represent a string like `2021-01-08`
 */
type TDateISODate = `${TYear}-${TMonth}-${TDay}`;

/**
 * Represent a string like `14:42:34.678`
 */
type TDateISOTime = `${THours}:${TMinutes}:${TSeconds}.${TMilliseconds}`;

/**
 * Represent a string like `2021-01-08T14:42:34.678Z` (format: ISO 8601).
 *
 * It is not possible to type more precisely (list every possible values for months, hours etc) as
 * it would result in a warning from TypeScript:
 *   "Expression produces a union type that is too complex to represent. ts(2590)
 */
type TDateISO = `${TDateISODate}T${TDateISOTime}Z`;

source

66bbxpm5

66bbxpm54#

您可以使用io-ts-types中的DateFromISOString,请参阅其documentation

相关问题