![](/img/trans.png)
[英]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.