基于字符串联合类型的条件类型触发TS2344错误
问题:条件类型分支触发TS2344约束错误
基于字符串联合类型ColumnType创建条件类型Column时,最后一个分支触发TS2344错误。按逻辑此时Type应已排除"calculated"和"enum",但TypeScript仍提示类型不满足约束。
代码实现:
// 可用的列类型 export type ColumnType = | "boolean" | "calculated" | "country" | "date" | "enum" | "int" | "language" | "price" | "string" // 仅用于创建列类型的模板接口,不会在其他地方使用 interface ColumnTemplate<Type extends ColumnType> { id: string title: string type: Type } // 部分列类型有额外字段(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> // 最终要使用的列类型 export type Column<ItemType, Type extends ColumnType> = Type extends "calculated" ? CalculatedColumn<ItemType> : Type extends "enum" ? EnumColumn : OtherColumn<Type> // ^^^^ 错误发生在此处
错误提示:
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)
解决方案:
TypeScript的条件类型分支检查不会自动缩小泛型参数的约束范围,即使逻辑上Type已经排除了"calculated"和"enum",编译器也无法自动推导这一点。可以通过以下方式修复:
方式一:直接使用ColumnTemplate<Type>替代OtherColumn<Type>
OtherColumn本质是ColumnTemplate的别名,只是增加了Type extends OtherType的约束。既然逻辑上Type此时必然属于OtherType,直接使用ColumnTemplate<Type>即可绕过约束检查:
export type Column<ItemType, Type extends ColumnType> = Type extends "calculated" ? CalculatedColumn<ItemType> : Type extends "enum" ? EnumColumn : ColumnTemplate<Type>
方式二:用Extract手动缩小Type范围
通过Extract<Type, OtherType>明确告诉编译器,此时Type属于OtherType的子集,满足OtherColumn的约束:
export type Column<ItemType, Type extends ColumnType> = Type extends "calculated" ? CalculatedColumn<ItemType> : Type extends "enum" ? EnumColumn : OtherColumn<Extract<Type, OtherType>>
内容的提问来源于stack exchange,提问作者Vinorcola
相关产品推荐
相关产品推荐

