打字稿:将对象属性和嵌套对象属性的类型更改为一种类型
Typescript: change type of object properties and nested object properties to one type
有这个例子:
interface Event {
title:string;
description:string;
fromDate: Date;
toDate: Date;
location: {
name: string;
lat: number;
long: number;
}
}
使用类似于 PropertiesToString<Event>
的类型我希望 return 这种类型:
{
title:string;
description:string;
fromDate: string;
toDate: string;
location: {
name: string;
lat: string;
long: string;
}
}
问题是如何创建 PropertiesToString<T>
类型?
我已经设法创建了一些可以工作但不适用于嵌套对象的东西。如果我有一个嵌套对象而不是将对象属性修改为字符串,它会将对象设置为字符串。
这是我的版本,不适用于嵌套对象,因为它不会更改 location properties to string
的类型,而是更改 location itself to string
:
的类型
export type RequestBody<T> = {
[P in keyof T]: string;
};
type ToString
将给定类型转换为 string
。 PropertiesToString
遍历传递类型的每个键并使用 ToString
将其类型更改为 string
。您可以使用类型三元运算符在 ToString
中添加您想要处理的其他特殊情况。
interface Event1 {
title: string;
description: string;
fromDate: Date;
toDate: Date;
location: {
name: string;
lat: number;
long: number;
}
}
type ToString<T> = T extends Date
? string
: T extends object
? PropertiesToString<T>
: string
type PropertiesToString<T> = {
[K in keyof T]: ToString<T[K]>
}
type Generated = PropertiesToString<Event1>
type X = PropertiesToString<Event1['location']>
const x: Generated = {
title: 'lorem',
description: 'lorem',
fromDate: 'lorem',
toDate: 'lorem',
location: {
name: 'lorem',
lat: 'lorem',
long: 'lorem',
}
}
你们其实很亲近。但是,您可能必须处理一些边缘情况。在 JS 中很多东西都是对象,你可能不希望它们都简单地变成字符串。所以你可能需要用更多的逻辑来增强它。但最简单的
type RecursiveObject<T> = T extends Date ? never : T extends object ? T : never;
export type StringValues<TModel> = {
[Key in keyof TModel]: TModel[Key] extends RecursiveObject<TModel[Key]> ? StringValues<TModel[Key]> : string;
};
添加您需要在代码中处理的任何特殊情况(数组?其他包装类型?)。最终我们会在类型中得到“不”处理,这样会简单很多。
另一种方法可以是:
// Do not control Date type here
type RecursiveObject<T> = T extends Date? never : T extends object ? T : never;
// Change properties (nested, or not) OT (Old Type) to NT (New Type)
type ToNewType<T, NT> = { [K in keyof T]: NT };
type NestedTypeChange<T, OT, NT> = {
[k in keyof T]: T[k] extends OT ? NT : T[k] extends RecursiveObject<T[k]> ? ToNewType<NestedTypeChange<T[k], OT, NT>, NT> : NT
}
有这个例子:
interface Event {
title:string;
description:string;
fromDate: Date;
toDate: Date;
location: {
name: string;
lat: number;
long: number;
}
}
使用类似于 PropertiesToString<Event>
的类型我希望 return 这种类型:
{
title:string;
description:string;
fromDate: string;
toDate: string;
location: {
name: string;
lat: string;
long: string;
}
}
问题是如何创建 PropertiesToString<T>
类型?
我已经设法创建了一些可以工作但不适用于嵌套对象的东西。如果我有一个嵌套对象而不是将对象属性修改为字符串,它会将对象设置为字符串。
这是我的版本,不适用于嵌套对象,因为它不会更改 location properties to string
的类型,而是更改 location itself to string
:
export type RequestBody<T> = {
[P in keyof T]: string;
};
type ToString
将给定类型转换为 string
。 PropertiesToString
遍历传递类型的每个键并使用 ToString
将其类型更改为 string
。您可以使用类型三元运算符在 ToString
中添加您想要处理的其他特殊情况。
interface Event1 {
title: string;
description: string;
fromDate: Date;
toDate: Date;
location: {
name: string;
lat: number;
long: number;
}
}
type ToString<T> = T extends Date
? string
: T extends object
? PropertiesToString<T>
: string
type PropertiesToString<T> = {
[K in keyof T]: ToString<T[K]>
}
type Generated = PropertiesToString<Event1>
type X = PropertiesToString<Event1['location']>
const x: Generated = {
title: 'lorem',
description: 'lorem',
fromDate: 'lorem',
toDate: 'lorem',
location: {
name: 'lorem',
lat: 'lorem',
long: 'lorem',
}
}
你们其实很亲近。但是,您可能必须处理一些边缘情况。在 JS 中很多东西都是对象,你可能不希望它们都简单地变成字符串。所以你可能需要用更多的逻辑来增强它。但最简单的
type RecursiveObject<T> = T extends Date ? never : T extends object ? T : never;
export type StringValues<TModel> = {
[Key in keyof TModel]: TModel[Key] extends RecursiveObject<TModel[Key]> ? StringValues<TModel[Key]> : string;
};
添加您需要在代码中处理的任何特殊情况(数组?其他包装类型?)。最终我们会在类型中得到“不”处理,这样会简单很多。
另一种方法可以是:
// Do not control Date type here
type RecursiveObject<T> = T extends Date? never : T extends object ? T : never;
// Change properties (nested, or not) OT (Old Type) to NT (New Type)
type ToNewType<T, NT> = { [K in keyof T]: NT };
type NestedTypeChange<T, OT, NT> = {
[k in keyof T]: T[k] extends OT ? NT : T[k] extends RecursiveObject<T[k]> ? ToNewType<NestedTypeChange<T[k], OT, NT>, NT> : NT
}