typescript 基于字符串联合的条件类型失败,错误为2344

h9a6wy2h  于 2023-03-04  发布在  TypeScript
关注(0)|答案(1)|浏览(145)

我试图创建一个基于字符串联合类型的条件类型,但是在条件类型中的最新选项出现错误2344。

// Those are available column types.
export type ColumnType =
    | "boolean"
    | "calculated"
    | "country"
    | "date"
    | "enum"
    | "int"
    | "language"
    | "price"
    | "string"

// This is a template interface only used for creating column's types bellow, it won't be used elsewhere.
interface ColumnTemplate<Type extends ColumnType> {
    id: string
    title: string
    type: Type
}

// Some column's types will have extra fiels (calculated & enum)
type CalculatedColumn<ItemType> = ColumnTemplate<"calculated"> & {
    resolver: (item: ItemType) => string | null
}

type EnumColumn = ColumnTemplate<"enum"> & {
    dictionary: Map<string, string>
}

type OtherType = Exclude<ColumnType, "calculated" | "enum">
type OtherColumn<Type extends OtherType> = ColumnTemplate<Type>

// This is our final column type that we want to use.
export type Column<ItemType, Type extends ColumnType> = Type extends "calculated"
    ? CalculatedColumn<ItemType>
    : Type extends "enum"
    ? EnumColumn
    : OtherColumn<Type>
//                ^^^^ Error is here

错误出现在最后一行:

Type 'Type' does not satisfy the constraint 'OtherType'.
  Type 'ColumnType' is not assignable to type 'OtherType'.
    Type '"calculated"' is not assignable to type 'OtherType'.(2344)

OtherColumn<Type>不应为"calculated",因为此类型应解析为CalculatedColumn ...
这里是Playground

eyh26e7m

eyh26e7m1#

条件类型并不总是像我们希望的那样强大!在这个例子中,最后一行中的Type实际上被缩小到Exclude<ColumnType, "enum">,因为内部条件,而不是我们在嵌套上下文中期望的Exclude<Exclude<ColumnType, "enum">, "calculated">
你可以通过重新排序来解决这个问题:

export type Column<ItemType, Type extends ColumnType> =
    Type extends OtherType
        ? OtherColumn<Type>
        : Type extends "calculated"
            ? CalculatedColumn<ItemType>
            : EnumColumn

这是因为EnumColumn不依赖于Type
或者,您可以使用交集显式地缩小类型:

export type Column<ItemType, Type extends ColumnType> =
    Type extends "calculated"
        ? CalculatedColumn<ItemType>
        : Type extends "enum"
            ? EnumColumn
            : OtherColumn<Type & OtherType>

相关问题