[英]Infer Typescript class to return the generic type based of generic value
[英]TypeScript Generic infer based on field
enum Letter {
A = "A",
B = "B",
C = "C"
}
export type EntityT<T extends Letter = Letter> = T extends Letter.A
? { a: number }
: T extends Letter.B
? { b: string }
: T extends Letter.C
? { c: string }
: never;
type DeltaT<T extends EntityT> = _DeltaT<T, keyof T>;
export type _DeltaT<E extends EntityT, K extends keyof E> = {
key: K;
oldValue: E[K];
newValue: E[K];
};
export type ProblemT<T extends Letter = Letter> = EntityT<T> extends infer E
? {
id: string;
type: T;
delta: DeltaT<E>[];
oldEntity: E;
newEntity: E;
}
: never;
const testCase: ProblemT<Letter.A> = {
id: "id",
type: Letter.A,
delta: [{ key: "a", oldValue: 1, newValue: 2 }],
oldEntity: { a: 1 },
newEntity: { a: 2 }
};
function myFunc<T extends Letter>(e: ProblemT<T>) {
switch (e.type) {
case Letter.A: {
const uselessConversion = e as ProblemT<Letter.A>;
return uselessConversion.newEntity.a;
}
case Letter.B: {
const uselessConversion = e as ProblemT<Letter.B>;
return uselessConversion.newEntity.b;
}
case Letter.C: {
const uselessConversion = e as ProblemT<Letter.C>;
return uselessConversion.newEntity.c;
}
}
}
我想聲明一個類型ProblemT
,它取決於他的type
鍵,將在oldEntity
和newEntity
返回不同的值。 我想使用 switch 運行myFunc
而無需手動轉換對象,TypeScript 將根據type
屬性推斷type
。 但效果不佳。 如何讓開關自動推斷類型而不需要轉換。 有沒有更好的方法來聲明ProblemT
不同類型,以便 switch 可以推斷出它?
這是TypeScript 游樂場的鏈接
請注意,諸如Letter.A | Letter.B
類的類型 Letter.A | Letter.B
還擴展了Letter
,因此編譯器不知道事物像它們一樣受到約束。
像這樣的事情會起作用:
enum Letter {
A = "A",
B = "B",
C = "C"
}
export type EntityT<T extends Letter> =
T extends Letter.A ? { a: number }
: T extends Letter.B ? { b: string }
: T extends Letter.C ? { c: string }
: never;
export type DeltaT<T extends Letter, K = keyof EntityT<T>> = K extends keyof EntityT<T>
? {
key: K;
oldValue: EntityT<T>[K];
newValue: EntityT<T>[K];
}
: never;
export type ProblemT<T extends Letter> = {
id: string;
type: T;
delta: DeltaT<T>[];
oldEntity: EntityT<T>;
newEntity: EntityT<T>;
};
function myFunc(e: ProblemT<Letter.A> | ProblemT<Letter.B> | ProblemT<Letter.C>) {
switch (e.type) {
case Letter.A: return e.newEntity.a;
case Letter.B: return e.newEntity.b;
case Letter.C: return e.newEntity.c;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.