类型'never[]'不能赋值给类型'...'。

3

'never[]'类型不能分配给类型 '...'

由于这个随机错误,我无法初始化类中的属性items。我认为将泛型类类型扩展为Array<string>将确保该类型始终为字符串数组?

class MyClass<TItems extends Array<string>> {
    constructor() {
        this.items = [];
    }

    public items: TItems;
}

报错信息如下:

无法将类型“string”赋值给类型“TItems”。 “string”可分配给类型“TItems”的约束,但“TItems”可能用不同的子类型的约束进行实例化。ts(2322)

1个回答

2

问题

您可能知道一个子类型可以分配给超类型,但反过来则不成立。因此,在以下代码和内联解释中-

class A extends Array<string> {
  public myProp!: string
}

// it is ok to assign a subtype to its supertype
// because subtype has atleast all those props/methods
// that a supertype has
declare const a1: A
const array1: Array<string> = a1

// it is an error to assign supertype to one of its subtype
// (until they are structurally same)
// because the supertype (array2) may have some missing props/methods
// (myProp in this case) that its subtype has.
declare const array2: Array<string>
const a2: A = array2

游乐场

在你的代码中,TItemsArray<string> 的子类型,而 [] 的类型是 never[]
如果你使用了 [] as Array<string> 进行类型转换,那么超类型(Array<string>)就不能被赋值给子类型 TItemsPlayground

如果你使用了[] as TItems进行类型转换,那么这个类型转换本身也是错误的,原因与之前相同。Playground

解决方案

可以通过以下方式进行类型转换来消除错误-

class MyClass<TItems extends Array<string>> {
    public items: TItems;

    constructor() {
        this.items = [] as unknown as TItems;
    }
}

游乐场

但是这可能会导致运行时错误,因为它不是“安全”的类型转换。

为了避免运行时错误,正确的方法是使用类TItems的构造函数或返回TItems的函数初始化属性items,而不是= []。 这将消除类型错误,并确保没有运行时错误。 两种方法都演示如下-

// if a passed TItems is supposed to class
// we pass that constructor of the class 
// constructor of `MyClass`
class MyClass<TItems extends Array<string>> {
    public items: TItems;

    constructor(ctor: new () => TItems) {
        this.items = new ctor();
    }
}

class MyArray extends Array<string> {
  private myProp!: string
}

const myClassVar = new MyClass(MyArray)

游乐场

// if a passed TItems is supposed to be just a type
// we pass a function that will create that object of `TItems`
class MyClass<TItems extends Array<string>> {
    public items: TItems;

    constructor(fn: () => TItems) {
        this.items = fn();
    }
}

declare function createObject(): Array<string> & { myProp: string }

const myClassVar = new MyClass(createObject)

游��场


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接