【发布时间】:2020-10-08 03:47:09
【问题描述】:
我有类似以下的内容:
declare class Base {
constructor(a: string)
}
declare class A extends Base {
constructor(a: number)
}
declare class B extends Base {
constructor(a: object)
}
declare class C extends Base {
constructor(a: boolean)
}
type ResponseMapper<T extends Base> = T extends A
? number
: T extends B
? object
: T extends C
? boolean
: never;
declare function getValue<T extends Base>(input: T): ResponseMapper<T>
let x: number = getValue(new A(1))
let y: object = getValue(new B({}))
let z: boolean = getValue(new C(true))
这并不完全有效,因为 A、B 和 C 在结构上都是等效的。所以在ResponseMapper 中,如果我传入B 或C 的实例,它仍然会计算为number。所以y 和z 的变量声明最终会出现类型错误。
我想出一个解决方法是为每个类添加一个假属性,使类型在结构上不再是等效的。所以这行得通:
declare class Base {
constructor(a: string)
}
declare class A extends Base {
_name?: "A"
constructor(a: number)
}
declare class B extends Base {
_name?: "B"
constructor(a: object)
}
declare class C extends Base {
_name?: "C"
constructor(a: boolean)
}
type ResponseMapper<T extends Base> = T extends A
? number
: T extends B
? object
: T extends C
? boolean
: never;
declare function getValue<T extends Base>(input: T): ResponseMapper<T>
let x: number = getValue(new A(1))
let y: object = getValue(new B({}))
let z: boolean = getValue(new C(true))
有没有更好的方法来让它工作而不需要添加假字段?
【问题讨论】:
标签: typescript