简体   繁体   English

Typescript 覆盖字符串文字的类型

[英]Typescript Overriding Type of String Literals

I currently have the following setup:我目前有以下设置:


enum EnumA {
    A,
    AYE
}

enum EnumB {
    B,
    BEE
}

type A = keyof typeof EnumA
type B = keyof typeof EnumB

type AB = A | B

interface IBase {
    foo: (...ok: AB[]) => IBase
}

abstract class Base implements IBase {
    public foo(...ok: AB[]): Base {
        return this
    }
}

class BaseA extends Base implements IBase {
    public override foo(...ok: A[]): Base {
        return super.foo(...ok)
    }
}

class BaseB extends Base implements IBase {
    public override foo(...ok: B[]): Base{
        return super.foo(...ok)
    }
}

const myA: BaseA = new BaseA()

I expect that overriding the type of "ok" in the subclasses of Base and implementation of IBase should work, however typescript complains:我希望覆盖 Base 的子类中的“ok”类型和 IBase 的实现应该有效,但是 typescript 抱怨:

Property 'foo' in type 'BaseA' is not assignable to the same property in base type 'IBase'.类型“BaseA”中的属性“foo”不可分配给基类型“IBase”中的同一属性。 Type '(...ok: ("A" | "AYE")[]) => Base' is not assignable to type '(...ok: AB[]) => IBase'.类型 '(...ok: ("A" | "AYE")[]) => Base' 不可分配给类型 '(...ok: AB[]) => IBase'。 Types of parameters 'ok' and 'ok' are incompatible.参数类型“ok”和“ok”不兼容。 Type 'AB' is not assignable to type '"A" |类型 'AB' 不可分配给类型 '"A" | "AYE"'. “是”。 Type '"B"' is not assignable to type '"A" |类型“B”不能分配给类型“A” | "AYE"'.ts(2416) “啊”'.ts(2416)

Any ideas what is going wrong here?知道这里出了什么问题吗? I'd like to call myA.foo() with type declarations that represent the type A, being a subset of type AB.我想用代表类型 A 的类型声明调用myA.foo() ,它是类型 AB 的子集。

Any help would be greatly appreciated.任何帮助将不胜感激。

You are declaring an interface that expects A|B as an argument to a method.您正在声明一个期望A|B作为方法参数的接口。 Any class that implements that interface must respect the contract .任何实现该接口的 class 都必须respect the contract This means that passing either A or B must be acceptable.这意味着通过AB必须是可以接受的。 When you are narrowing the type you are actually violating the contract for either A or B and this is not ok.当您缩小类型时,您实际上违反了AB的合同,这是不行的。 What you probably want are generics.您可能需要的是 generics。

enum EnumA {
    A,
    AYE
}

enum EnumB {
    B,
    BEE
}

type A = keyof typeof EnumA
type B = keyof typeof EnumB

type AB = A | B

interface IBase <T> {
    foo: (ok: T) => IBase<T>
}

abstract class Base <T> implements IBase<T> {
    public foo(...ok: T[]): Base<T> {
        return this
    }
}

class BaseA extends Base<A> implements IBase<A> {
    public override foo(...ok: A[]): Base<A> {
        return super.foo(...ok)
    }
}

class BaseB extends Base<B> implements IBase<B> {
    public override foo(...ok: B[]): Base<B>{
        return super.foo(...ok)
    }
}

const myA: BaseA = new BaseA()

Here's a playground link这是游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM