typescript - 类型 'never[]' 不能分配给类型 '...'
问题描述
由于这个随机错误,我无法初始化我班级的属性项。我想扩展泛型类类型以Array<string>
确保该类型始终是字符串数组?
class MyClass<TItems extends Array<string>> {
constructor() {
this.items = [];
}
public items: TItems;
}
给我错误:
类型“字符串”不可分配给类型“TItems”。“string”可分配给“TItems”类型的约束,但“TItems”可以用约束“string”的不同子类型实例化。ts(2322)
解决方案
问题
您可能熟悉可以将子类型分配给超类型的事实,但反之亦然。因此,在以下代码和内联解释中 -
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
在您的代码中,TItems
是 的子类型Array<string>
,而类型[]
是never[]
。
如果您使用 对其进行了类型转换,则无法[] as Array<string>
将超类型 ( ) 分配给子类型。操场Array<string>
TItems
如果您使用 对其进行[] as TItems
了类型转换,则出于同样的原因,类型转换本身就是错误的。操场
解决方案
可以通过类型转换为错误来消除该错误-
class MyClass<TItems extends Array<string>> {
public items: TItems;
constructor() {
this.items = [] as unknown as TItems;
}
}
但这可能会导致运行时错误,因为它不是“安全”的类型转换。
为了避免运行时错误,正确的方法是使用返回items
的类TItems
或函数的构造函数来初始化 prop,TItems
而不是= []
. 这将消除类型错误并确保不会出现运行时错误。两种方式都得到证明——
// 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)
推荐阅读
- vba - 排序如何影响约会搜索的结果?
- java - 使用 Arraylist Java 进行选举
- vue.js - 在 VuePress 中显示 Vue 组件
- swift - Swift:RegEx 未返回预期结果
- javascript - Plotly js gd.data 必须是一个数组
- c# - ZeroMQ (NetMQ) Dealer / Router Socket 可扩展性问题
- python - 破解 RSA Chipher / 如何从 N 中得到 p,q?
- graphql - 将@client 片段与远程片段混合不起作用
- vue.js - 在 VueJS 组件中,如何将 Table 与来自子组件的数据行一起使用
- azure-active-directory - 无法从图形资源管理器将组添加到我的天蓝色活动目录