我是打字稿的新手,所以我正在努力掌握它。
网络请求将返回一个带有 ISO 日期字符串格式字段的 JSON 对象。
data : Data = {when: "2016-07-13T18:46:01.933Z"}
Run Code Online (Sandbox Code Playgroud)
当我为这个接口创建类型签名时,有什么方法可以指定这实际上是一个 ISO 时间戳还是我只需要使用字符串?
interface Data {
when: string
}
Run Code Online (Sandbox Code Playgroud)
我发现我可以使用一个在精神上有帮助的类型别名,但并没有真正验证 ISO 字符串。
type iso = string
interface Data {
when: iso
}
Run Code Online (Sandbox Code Playgroud)
同样,我很好奇是否有办法从这些打字稿注释生成 js 验证,以便我可以验证端点接收到的信息,否则我键入的应用程序的其余部分毫无价值。
如果这是可能的,那么如果可以将此 iso 字符串强制转换为实际的 Date 对象,那就太酷了。
正如我所说,我是打字稿的新手,所以我不确定这是否超出了打字稿应该做的范围。
小智 10
// 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`;
Run Code Online (Sandbox Code Playgroud)
来源
不,这是不可能的。对于 javascript,与 typescript 的接口无关。(JS 根本不会为接口生成)。此外,所有类型检查都是在“编译”或“编译”时完成的,而不是在运行时完成。
您可以做的是reviver在解析json时使用函数。例如:
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;
});
Run Code Online (Sandbox Code Playgroud)
您也可以Date通过键来识别属性,如果它与日期模式不匹配,您可以抛出错误或做任何您想做的事情。
您可以使用类型保护。
import moment from 'moment'
export const isISO = (input: any): input is tISO =>
moment(input, moment.ISO_8601, true).isValid()
Run Code Online (Sandbox Code Playgroud)
然后你可以使用任何你想要处理任何错误日期的自定义逻辑,例如:
const maybeISO = fetch('Maybe ISO')
if (isISO(maybeISO)) {
// proceed
} else {
// check other format?
// log error?
}
Run Code Online (Sandbox Code Playgroud)
干杯。