在类中,我知道一个属性将是基于另一个属性的有区别的联合之一,但是我不知道如何使TypeScript反映出来。
我尝试扩展如下所示的有区别的联合,但这是行不通的。
type A = { thing: 1, otherThing: string }
type B = { thing: 2, otherThing: number }
type C = A | B;
// ERROR: A class can only implement an object type or intersection
// of object types with statically known members. ts(2422)
class C implements C {
// ...
}
该方法有效,但是这个问题是看我是否可以使它用吸气剂代替方法。
class Example {
thing: 1 | 2;
get otherThing() {
if (this.thing === 1) return 'one';
return 2;
}
getOtherThing(thing: 1): string;
getOtherThing(thing: 2): number;
getOtherThing(): string | number {
if (this.thing === 1) return 'one';
return 2;
}
constructor(value: Example['thing']) {
this.thing = value;
}
fails() {
// I'd really like this type of logic to work
if (this.thing === 1) {
// Type '2 | "one"' is not assignable to type 'string'.
const test: string = this.otherThing;
}
}
works() {
if (this.thing === 1) {
const test: string = this.getOtherThing(this.thing);
}
}
}
编辑:具体来说,此问题是在同一类中使用的。 solution provided by @jcalz非常好,如果我无法找到想要的结果,那么我可以将其与组成结合使用以达到相似的结果。
答案 0 :(得分:0)
单个类或接口无法扩展或实现事物的并集,因此无法直接实现您想要的东西。如果您真的需要一个类来给您像被歧视的联合一样的行为,我会考虑使用一个generic类,其中您的依赖属性为conditional type:
class Example<T extends C["thing"]> {
constructor(
public thing: T,
public otherThing: Extract<C, { thing: T }>["otherThing"]
) {}
}
在判别属性thing
是有效键类型(并且1 | 2
有效)的特定实例中,您可以使用mapped types代替条件类型(尽管我将使用映射出像这样的条件类型):
type MappedOtherThing = {
[K in C["thing"]]: Extract<C, { thing: K }>["otherThing"]
};
class Example<T extends C["thing"]> {
constructor(public thing: T, public otherThing: MappedOtherThing[T]) {}
}
Extract<C, {thing: T}>["otherThing"]
使用Extract
实用程序类型查找可分配给C
的{{1}}成员,然后looks up为其{{1} }属性。
这些实现中的任何一种都会给您以下行为:
{thing: T}
希望有帮助。祝你好运!