打字稿如何使映射类型扩展 typeof Class
Typescript how to make a mapped type extends typeof Class
Typescript 映射类型语法对我来说真的很晦涩,但我会尽量让自己清楚。
基本上我想要一个类型过滤器来 return 我只有一个对象的键具有 Class 类型或 classes 的数组。经过一些尝试,我得到了这个:
type OnlyObjectProperties<T> = {
[key in keyof T]: T[key] extends object ? key : never;
}[keyof T];
export type ClassRelation<T> = {
[key in keyof Pick<T, OnlyObjectProperties<T>>]: string;
};
但我希望 OnlyObjectProperties<T>
仅 return 类型为 class 的键。
例如:
class Person{
name: string;
task: Task // consider that Task class is defined.
}
const test: ClassRelation<Person> = {tasks: 'tasks'} // only the task key should appear and be allowed on the test variable
我已经试过这样的东西了:
type OnlyObjectProperties<T> = {
[key in keyof T]: T[key] extends new(...args: any[]) => any? key : never;
}[keyof T];
但是没有成功。
总而言之,我想要给定类型的键,其类型为 Class
这是我一直用来制作原型的 stackblitz https://stackblitz.com/edit/ts-node-gckhuf?file=index.ts
您无法真正将 class
的实例与 TypeScript 或 JavaScript 中的任何其他 object
区分开来。所有对象都有 constructor
属性,甚至像 Date
这样原生提供的对象也是如此。相反,您需要找到一些方法来识别您想要保留的 class 个实例,并将它们 structurally 与其他对象类型区分开来。
您提供的示例 classes 如下所示:
class User {
id!: number;
createdAt!: Date;
tasks!: Task[];
}
class Task {
id!: number;
doneAt!: Date;
user!: User
}
两者都有 id
属性 类型 number
。如果这是区分好的 class 实例和坏实例的好方法,那么您可以相应地更改类型函数:
export type ClassRelation<T> = {
[K in keyof Pick<T, OnlyPropertiesWithANumericId<T>>]: string;
};
type OnlyPropertiesWithANumericId<T> = {
[K in keyof T]: T[K] extends { id: number } ? K : never;
}[keyof T];
您可以验证它是否按预期工作:
const onlyRelationsFromTask: ClassRelation<Task> = {
user: "user"
}
Typescript 映射类型语法对我来说真的很晦涩,但我会尽量让自己清楚。
基本上我想要一个类型过滤器来 return 我只有一个对象的键具有 Class 类型或 classes 的数组。经过一些尝试,我得到了这个:
type OnlyObjectProperties<T> = {
[key in keyof T]: T[key] extends object ? key : never;
}[keyof T];
export type ClassRelation<T> = {
[key in keyof Pick<T, OnlyObjectProperties<T>>]: string;
};
但我希望 OnlyObjectProperties<T>
仅 return 类型为 class 的键。
例如:
class Person{
name: string;
task: Task // consider that Task class is defined.
}
const test: ClassRelation<Person> = {tasks: 'tasks'} // only the task key should appear and be allowed on the test variable
我已经试过这样的东西了:
type OnlyObjectProperties<T> = {
[key in keyof T]: T[key] extends new(...args: any[]) => any? key : never;
}[keyof T];
但是没有成功。
总而言之,我想要给定类型的键,其类型为 Class
这是我一直用来制作原型的 stackblitz https://stackblitz.com/edit/ts-node-gckhuf?file=index.ts
您无法真正将 class
的实例与 TypeScript 或 JavaScript 中的任何其他 object
区分开来。所有对象都有 constructor
属性,甚至像 Date
这样原生提供的对象也是如此。相反,您需要找到一些方法来识别您想要保留的 class 个实例,并将它们 structurally 与其他对象类型区分开来。
您提供的示例 classes 如下所示:
class User {
id!: number;
createdAt!: Date;
tasks!: Task[];
}
class Task {
id!: number;
doneAt!: Date;
user!: User
}
两者都有 id
属性 类型 number
。如果这是区分好的 class 实例和坏实例的好方法,那么您可以相应地更改类型函数:
export type ClassRelation<T> = {
[K in keyof Pick<T, OnlyPropertiesWithANumericId<T>>]: string;
};
type OnlyPropertiesWithANumericId<T> = {
[K in keyof T]: T[K] extends { id: number } ? K : never;
}[keyof T];
您可以验证它是否按预期工作:
const onlyRelationsFromTask: ClassRelation<Task> = {
user: "user"
}