打字稿将所有日期从接口转换为字符串

时间:2020-12-23 07:18:14

标签: typescript typescript-typings

是否可以将所有 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,对应于 itemitem2 的转换。所以 itemitem2 不同,应该保持不同,因此我需要一个新的 item2 接口。当然,我可以手动完成,但是我有一堆要转换的界面,我想用类似于实用程序类型的东西来做到这一点:https://www.typescriptlang.org/docs/handbook/utility-types.html

注意 2: 目标是获得一个名为 Item2

的新界面
interface Item2 {
   key: string;
   value: number;
   created: string;
}

类似于type Item2 = ToJSON<Item>

4 个答案:

答案 0 :(得分:3)

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 的属性转换为字符串。

答案 1 :(得分:0)

也许可以考虑将 Item 声明为一个类。 有许多库可以帮助将普通对象转换为类实例,例如class-transformer

答案 2 :(得分:0)

好的,看看这个太棒了,我从这个家伙的帖子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
}

答案 3 :(得分:0)

在这种情况下,需要 2 种类型,除了单个字段的类型注释之外,其他类型都相同。

解决方案:通用接口

使接口通用将允许您使用类型参数对其进行参数化,并在您的两种类型中重复使用它。请参阅 TypeScript generics 了解更多信息。

将此应用于您的示例:

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);
相关问题