我正在寻找一种方法来避免在以下接口声明中重复 T["uuid"]:
export interface Foo<T extends { uuid: unknown; name: string } > {
getAll(): Promise<T[]>;
getAllIn(ids: T["uuid"][]): Promise<T[]>;
findOne(id: T["uuid"]): Promise<T | null>;
findOneByName(name: string): Promise<T | null>;
getOne(id: T["uuid"]): Promise<T>;
addOne(item: T): Promise<void>;
deleteOne(id: T["uuid"]): Promise<void>;
updateOne(item: T): Promise<void>;
}
有没有办法获得 T["uuid"] 的别名之类的东西?
不,你不能有本地范围的类型别名。在 microsoft/TypeScript#23188 上有一个对此类功能的长期开放请求,但目前它还不是该语言的一部分。
除非它被实现,否则您的选择是要么创建一个正常作用域的类型别名,例如
type U<T extends { uuid: any }> = T["uuid"];
interface Foo<T extends { uuid: unknown; name: string }> {
getAll(): Promise<T[]>;
getAllIn(ids: U<T>[]): Promise<T[]>;
findOne(id: U<T>): Promise<T | null>;
findOneByName(name: string): Promise<T | null>;
getOne(id: U<T>): Promise<T>;
addOne(item: T): Promise<void>;
deleteOne(id: U<T>): Promise<void>;
updateOne(item: T): Promise<void>;
}
每次提及该类型都可以节省几次击键...
或者,您可以滥用默认类型参数(如上面的 ms/TS#23188 中所述)
interface Foo<T extends { uuid: unknown; name: string }, U = T["uuid"]> {
getAll(): Promise<T[]>;
getAllIn(ids: U[]): Promise<T[]>;
findOne(id: U): Promise<T | null>;
findOneByName(name: string): Promise<T | null>;
getOne(id: U): Promise<T>;
addOne(item: T): Promise<void>;
deleteOne(id: U): Promise<void>;
updateOne(item: T): Promise<void>;
}
其中
Foo<T>
相当于 Foo<T, T["uuid"]>
,因此相当于您原来的 Foo<T>
。但默认设置并不是“真正”为此目的。编译器不能假设 U
将 always是
T["uuid"]
,因此可能会发生奇怪的事情(例如,没有什么可以阻止你编写 Foo<{uuid: string, name: string}, number>
)。Playground 代码链接