如何为辅助函数添加类型:根据前置属性值限制可接受属性
实现特定表别名的属性类型校验
当然可以实现这个功能,核心是通过泛型+类型映射让TypeScript根据传入的表别名,自动约束可传入的属性名称。具体改造步骤如下:
1. 建立表别名与对应接口的映射关系
先定义一个类型,把每个表别名和它对应的接口关联起来:
type TableAliasToInterface = { TABLE_A: ITableA; TABLE_B: ITableB; };
2. 改造generateTableAlias函数的类型定义
使用泛型关联alias和property的类型,让property只能是对应表接口的属性键:
const generateTableAlias = <T extends keyof TableAliasToInterface>({ alias, property, specificty = 1 }: { alias: T; property: keyof TableAliasToInterface[T]; specificty?: number }) => `${tableAliases.ENVIRONMENT_A[alias](specificty)}.${property}`;
完整代码示例
interface ITableBase { id: number; } interface ITableA extends ITableBase { name: string; } interface ITableB extends ITableBase { hobbies: string[]; } const tableAliases = { ENVIRONMENT_A: { TABLE_A: (specificty: number) => `__table_a__${specificty}__`, TABLE_B: (specificty: number) => `__table_b__${specificty}__`, } }; // 建立别名与接口的映射 type TableAliasToInterface = { TABLE_A: ITableA; TABLE_B: ITableB; }; const generateTableAlias = <T extends keyof TableAliasToInterface>({ alias, property, specificty = 1 }: { alias: T; property: keyof TableAliasToInterface[T]; specificty?: number }) => `${tableAliases.ENVIRONMENT_A[alias](specificty)}.${property}`; // 测试案例 const tableAlias1 = generateTableAlias({ alias: 'TABLE_A', property: 'hobbies' }) // TypeScript报错:类型"hobbies"不能赋值给类型"keyof ITableA" const tableAlias2 = generateTableAlias({ alias: 'TABLE_A', property: 'name' }) // 无报错 const tableAlias3 = generateTableAlias({ alias: 'TABLE_B', property: 'hobbies' }) // 无报错 const tableAlias4 = generateTableAlias({ alias: 'TABLE_B', property: 'name' }) // TypeScript报错
关键说明
- 泛型
T会捕获传入的alias的具体值,TypeScript会自动推断出对应的接口类型TableAliasToInterface[T]。 property的类型被约束为keyof TableAliasToInterface[T],也就是对应表接口的所有属性键(包括继承自ITableBase的id),传入不属于该表的属性时会直接触发类型错误。
内容的提问来源于stack exchange,提问作者Mike K
相关产品推荐
相关产品推荐

