为什么打字稿抱怨 XXX 可分配给类型 'T' 的约束,但 'T' 可以用约束 X 的不同子类型实例化?
Why typescript complains that XXX is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint X?
我的代码是这样的:
export interface TreeItem {
id: string;
children: this[];
collapsed?: boolean;
}
const createTreeItem = <T extends TreeItem>(): T => {
return {
id: 'root',
children: []
}
}
但是我在 createTreeItem
的 return 类型上得到一个错误,如下所示:
TS2322: 输入'{ id: string; children: 从不[]; }' 不可分配给类型 'T'。 '{ id: 字符串; children: 从不[]; }' 可分配给 'T' 类型的约束,但 'T' 可以使用约束 'TreeItem'.
的不同子类型实例化
我完全不知道这是什么意思。
有什么帮助吗?
您可以在 return 之后添加“作为 T”:
const createTreeItem = (): T => ({
编号:'root',
children: []
} 作为 T);
假设您按如下方式调用您的函数:
let node = createTreeItem<TreeItem>()
还好吧? return 类型 T
是 TreeItem
,而您的泛型函数被硬编码为 return 的对象实际上有一个类型可以将其限定为 TreeItem
:
{ id: string; children: never[]; }
但是给你的函数一个类型参数的目的是允许它被其他类型的 T
调用,只要它们扩展 TreeItem
。所以下面应该是一个合法的调用:
export interface BidiTreeItem {
id: string;
children: this[];
parent: this;
collapsed?: boolean;
}
let node = createTreeItem<BidiTreeItem>()
调用是合法的,因为BidiTreeItem
满足约束T extends TreeItem
。此调用的 return 类型在您的函数定义中声明为 BidiTreeItem
,但您的函数 returns 不是 BidiTreeItem
.
如果您再次重读错误消息,但考虑到上面的示例,现在您就会明白了。但以防万一,下面我将翻译每一条错误信息。注意第一句是结论,所以放在最后 table:
this part of the error message...
means this (using above example)...
'{ id: string; children: never[]; }' is assignable to the constraint of type 'T'
'{ id: string; children: never[]; }'
is consistent with the constraint T extends TreeItem
but 'T' could be instantiated with a different subtype of constraint 'TreeItem'.
but T
could be instantiated with a different subtype of TreeItem
, for example BidiTreeItem
.
TS2322: Type '{ id: string; children: never[]; }' is not assignable to type 'T'.
The object your function is returning is not guaranteed to be assignable to type T
, because T
could be some other subtype such as BidiTreeItem
.
我的代码是这样的:
export interface TreeItem {
id: string;
children: this[];
collapsed?: boolean;
}
const createTreeItem = <T extends TreeItem>(): T => {
return {
id: 'root',
children: []
}
}
但是我在 createTreeItem
的 return 类型上得到一个错误,如下所示:
TS2322: 输入'{ id: string; children: 从不[]; }' 不可分配给类型 'T'。 '{ id: 字符串; children: 从不[]; }' 可分配给 'T' 类型的约束,但 'T' 可以使用约束 'TreeItem'.
的不同子类型实例化我完全不知道这是什么意思。
有什么帮助吗?
您可以在 return 之后添加“作为 T”:
const createTreeItem = (): T => ({ 编号:'root', children: [] } 作为 T);
假设您按如下方式调用您的函数:
let node = createTreeItem<TreeItem>()
还好吧? return 类型 T
是 TreeItem
,而您的泛型函数被硬编码为 return 的对象实际上有一个类型可以将其限定为 TreeItem
:
{ id: string; children: never[]; }
但是给你的函数一个类型参数的目的是允许它被其他类型的 T
调用,只要它们扩展 TreeItem
。所以下面应该是一个合法的调用:
export interface BidiTreeItem {
id: string;
children: this[];
parent: this;
collapsed?: boolean;
}
let node = createTreeItem<BidiTreeItem>()
调用是合法的,因为BidiTreeItem
满足约束T extends TreeItem
。此调用的 return 类型在您的函数定义中声明为 BidiTreeItem
,但您的函数 returns 不是 BidiTreeItem
.
如果您再次重读错误消息,但考虑到上面的示例,现在您就会明白了。但以防万一,下面我将翻译每一条错误信息。注意第一句是结论,所以放在最后 table:
this part of the error message... | means this (using above example)... |
---|---|
'{ id: string; children: never[]; }' is assignable to the constraint of type 'T' |
'{ id: string; children: never[]; }' is consistent with the constraint T extends TreeItem |
but 'T' could be instantiated with a different subtype of constraint 'TreeItem'. |
but T could be instantiated with a different subtype of TreeItem , for example BidiTreeItem . |
TS2322: Type '{ id: string; children: never[]; }' is not assignable to type 'T'. |
The object your function is returning is not guaranteed to be assignable to type T , because T could be some other subtype such as BidiTreeItem . |