我正在尝试扩展类键并设置自定义值以进行验证。
class FindUserDto {
readonly _id?: string | object;
readonly email?: string;
readonly firstName?: string;
readonly lastName?: string;
}
我需要创建一个SortBy
类,该类应从FindUserDto
中获取键并将'ASC'
或'DESC'
验证为传入值。这样的事情。
class SortBy {
readonly email: 'ASC' | 'DESC';
readonly firstName: 'ASC' | 'DESC';
readonly lastName: 'ASC' | 'DESC';
}
但是我要避免复制和粘贴,这就是为什么我要使用打字稿来解决它。
我试图像这样的[K in keyof FindUserDto]
或[key: K]
这样的K extends {[T in keyof FindUserDto]}
动态设置键,但是它不起作用。 Typescript不允许实现这种流程。
目前最简单的解决方案是通过在内部传递类型来升级FindUserDto
类:
class FindUserDto<T>{
_id?: T;
readonly email?: T;
readonly firstName?: T;
readonly lastName?: T;
}
class SortBy extends FindUserDto<'ASC' | 'DESC'> {
}
但是我想得到一个更可重用的解决方案。有人尝试做类似的事情吗?
答案 0 :(得分:0)
您可以将Record
与keyof T
结合使用。使用这个SortBy
不会是一个类,它将是一个类型别名,您可以使用任何对象文字来实现它:
class FindUserDto {
readonly _id?: string | object;
readonly email?: string;
readonly firstName?: string;
readonly lastName?: string;
}
type SortBy = Record<keyof FindUserDto, 'ASC' | 'DESC'>
// type SortBy = Record<Exclude<keyof FindUserDto, "_id">, 'ASC' | 'DESC'> // or remove _id
let sortBy: SortBy = {
_id: "ASC",
email: "DESC",
firstName: "DESC",
lastName: "ASC"
}
或者您也可以将其实现为类,但是您将不得不重新声明字段(尽管编译器确保将所有字段都重新声明):
class SortBy implements Record<keyof FindUserDto, 'ASC' | 'DESC' | undefined> {
_id: "ASC" | "DESC"| undefined;
email: "ASC" | "DESC"| undefined;
firstName: "ASC" | "DESC"| undefined;
lastName: "ASC" | "DESC"| undefined;
}
如果不重新声明所有字段,则还可以创建一个伪类,假装为实现字段而设计,以利于编译器:
function sortByClass<T>() : new () => Record<keyof T, 'ASC' | 'DESC' | undefined> {
return class {} as any
}
class SortBy extends sortByClass<FindUserDto>() {
}
注意:由于未初始化字段,因此我在字段类型中添加了| undefined
,以使字段类型与实际可能性保持一致。仅在使用stricyNullChecks
时才重要。
答案 1 :(得分:0)
class FindUserDto {
readonly _id?: string | object;
readonly email?: string;
readonly firstName?: string;
readonly lastName?: string;
}
type Sortable <T> = {
[P in keyof T]: 'ASC' | 'DESC';
};
let a: Sortable<FindUserDto>;
a = { email: 'ASC', firstName: 'DESC', lastName: 'ASC' };
// a = { email: 'ASC', firstName: 'DESC', lastName: 'ASC123' }; //error
这是另一种解决方案with enums。