TypeScript如何判断类型是否为泛型参数?
解决泛型参数传入时返回模型联合类型的问题
当前的TypeToModel工具类型使用ModelType extends T的条件判断,仅当T完全等于ModelType联合类型时才返回BaseModel。但当传入泛型变量(如T extends ModelType)时,TypeScript会触发分配条件类型,将Models[T]解析为所有模型的联合类型,而非预期的BaseModel。
以下是两种可行的解决方案:
方案1:使用函数重载(推荐)
函数重载可以更直观地处理不同输入场景的返回类型,无需复杂的工具类型:
type BaseModel = { id: number }; type Models = { user: BaseModel & { name: string }, post: BaseModel & { title: string }, }; type ModelType = keyof Models; // 重载1:传入具体字面量类型,返回对应模型 function getModel<T extends ModelType>(modelType: T): Models[T]; // 重载2:传入联合类型或泛型变量,返回BaseModel function getModel(modelType: ModelType): BaseModel; function getModel(modelType: ModelType): BaseModel | Models[keyof Models] { return {} as unknown as any; } // 测试验证 const user = getModel('user'); // 类型:Models['user'](符合预期) const post = getModel('post'); // 类型:Models['post'](符合预期) const mixed = getModel(Math.random() > 0.5 ? 'user' : 'post'); // 类型:BaseModel(符合预期) function foo<T extends ModelType>(modelType: T) { const userC = getModel(modelType); // 类型:BaseModel(符合预期) }
方案2:修改TypeToModel工具类型
通过实现字面量类型判断,区分具体字面量和泛型/联合类型:
type BaseModel = { id: number }; type Models = { user: BaseModel & { name: string }, post: BaseModel & { title: string }, }; type ModelType = keyof Models; // 判断类型是否为可确定的字面量类型 type IsLiteral<T> = T extends string ? (string extends T ? false : true) : false; // 修改后的TypeToModel type TypeToModel<T extends ModelType> = IsLiteral<T> extends true ? Models[T] : BaseModel; function getModel<T extends ModelType>(modelType: T): TypeToModel<T> { return {} as unknown as TypeToModel<T>; } // 测试验证 const user = getModel('user'); // 类型:Models['user'](符合预期) const post = getModel('post'); // 类型:Models['post'](符合预期) const mixed = getModel(Math.random() > 0.5 ? 'user' : 'post'); // 类型:BaseModel(符合预期) function foo<T extends ModelType>(modelType: T) { const userC = getModel(modelType); // 类型:BaseModel(符合预期) }
内容的提问来源于stack exchange,提问作者Leo Jiang
相关产品推荐
相关产品推荐

