是否可以将所有
Date
类型定义从我的界面转换为string
,因为它在JSON stringify上自动转换为string
。
interface Item {
key: string;
value: number;
created: Date;
}
const item: Item = { key: 'abc', value: 1, created: Date() };
// convert to JSON
const itemJson = JSON.stringify(item);
// convert back itemJson to an object
const item2 = JSON.parse(itemJson);
// item2 is not of type `Item` as JSON.stringify convert Dates to strings
// so item2 is of type: { key: string; value: number; created: string; }
是否有一种功能可以将
Date
类型从我的界面转换为string
?有点像const item2: ToJSON<Item> = JSON.parse(itemJson);
注: 我不想将
item2.created
转换回 Date,但我想创建一个新的 interface
对应于从 item
到 item2
的转换。所以item
不同于item2
并且应该保持不同,因此我需要一个新的item2
界面。当然,我可以手动完成,但我有一堆接口要转换,我想用类似于实用程序类型的东西来做这个:https://www.typescriptlang.org/docs/handbook/utility- types.html
注2: 目标是获得一个名为
Item2
的新界面
interface Item2 {
key: string;
value: number;
created: string;
}
有点像
type Item2 = ToJSON<Item>
.
TypeScript 类型系统 FTW:
interface Item {
key: string;
value: number;
created: Date;
}
type SwapDatesWithStrings<T> = {
[k in keyof(T)]: (T[k] extends Date ? string : T[k]);
}
type JsonItems = SwapDatesWithStrings<Item>;
// JsonItems is the same as:
// interface JsonItems {
// key: string;
// value: number;
// created: string;
// }
它可以从基本类型
SwapDatesWithStrings
派生出泛型类型 T
,具有与 T
相同的一组属性,但属性类型有所不同:从 Date 派生的属性被转换为字符串。
在这种情况下,需要 2 种类型,除了单个字段的类型注释外,它们在其他方面是相同的。
使接口通用将允许您使用类型参数对其进行参数化,并在您的两种类型中重复使用它。有关更多信息,请参见TypeScript 泛型。
将此应用于您的示例:
interface Item<T> {
key: string;
value: number;
created: T;
}
const item: Item<Date> = { key: 'abc', value: 1, created: Date() };
// convert to JSON
const itemJson = JSON.stringify(item);
// convert back itemJson to an object
const item2: Item<string> = JSON.parse(itemJson);
好吧,看看这个真棒,我是从这篇文章中得到的How to handle ISO date strings in TypeScript?
所以他说你可以添加一个恢复的功能,所以让我们在这里将它应用到你的问题:
interface Item {
key: string;
value: number;
created: Date | string;
}
const item: Item = { key: 'abc', value: 1, created: Date() };
// convert to JSON
const itemJson = JSON.stringify(item);
// convert back itemJson to an object
// The juice is here, what you do is add the function as a second argument
const item2 = JSON.parse(itemJson, (key: any, value: any) => {
// and in here you do your extra stuff...
return Date.parse(value) ? new Date(value): value;
});
#Edit:需要注意的是,接口不会进入 JS,它们会被删除,所以如果你想确认你的接口可能具有字符串类型,那么可以像这样定义你的接口:
interface Item {
key: string;
value: number;
created: Date | string; // at least this way you are acknowledging a potential string type
}
扩展@alberto-chiesa 的答案,我们可以让它转换对象嵌套部分中的日期,并且也允许可选值:
type NestedSwapDatesWithStrings<T> = {
[k in keyof T]: T[k] extends Date | undefined
? string
: T[k] extends object
? NestedSwapDatesWithStrings<T[k]>
: T[k];
};
它本质上是递归地尝试将
Dates
转换为 strings