如何解析'X'可赋值给类型为'T'的约束,但'T'可以用约束的不同子类型

  • 本文关键字:约束 类型 何解析 赋值 typescript
  • 更新时间 :
  • 英文 :


我有这个TypeScript playground:

export function isBlue<T extends Mesh>(
object: unknown,
type: T | Array<T>,
): object is BlueNodeType<T> {
const array: Array<T> = Array.isArray(type) ? type : [type]
return (
object != null && typeof object === 'object' &&
'type' in object &&
typeof object.type === 'string' &&
array.includes((object as BlueNodeType<T>).type)
)
}
export enum Mesh {
Assertion = 'mesh-assertion',
}
export type BlueBaseType = {
color: 'blue'
}
export type BlueAssertionType = BlueBaseType & {
type: Mesh.Assertion
}
export type BlueMappingType = {
'mesh-assertion': BlueAssertionType
}
export type BlueNodeType<T extends Mesh> = BlueMappingType[T]

抛出以下错误:

Argument of type 'Mesh' is not assignable to parameter of type 'T'.
'Mesh' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Mesh'.(2345)

我怎么让它工作?在我的实际代码库中,我有一个具有40种类型的BlueMappingType,所以我希望它能够根据泛型类型参数选择正确的类型。

使用Array.prototype.includes是一个棘手的问题。为了使它工作,你可以尝试我的自定义includes:

const withTuple = <
List extends string[]
>(list: readonly [...List]) =>
(prop: string): prop is List[number] =>
list.includes(prop)
export function isBlue<T extends Mesh>(
object: unknown,
type: T | Array<T>,
): object is BlueNodeType<T> {
const array: Array<T> = Array.isArray(type) ? type : [type]
const includes = withTuple(array)
return (
object != null && typeof object === 'object' &&
'type' in object &&
typeof object.type === 'string' &&
includes(object.type)
)
}
export enum Mesh {
Assertion = 'mesh-assertion',
}
export type BlueBaseType = {
color: 'blue'
}
export type BlueAssertionType = BlueBaseType & {
type: Mesh.Assertion
}
export type BlueMappingType = {
'mesh-assertion': BlueAssertionType
}
export type BlueNodeType<T extends Mesh> = BlueMappingType[T]

游乐场

withTuple只是Array.prototype.includes的一个curry版本,但它可以与元组一起工作。

你可以查看我的文章更多的例子

最新更新