Typescript中如何给类型为keyof显式接口的函数参数设置默认值
问题根因
你最初的写法报错,是因为泛型T由调用方传入的props参数决定,TS无法保证固定的默认值['name', 'age']和任意符合T extends keyof Person的泛型实例兼容。你后续尝试用条件类型后reduce报错,是因为你定义的PropsOrDefault是联合类型,TS无法推导它一定是可遍历的数组类型,所以识别不到reduce方法。
最佳解决方案:函数重载
直接用TS函数重载分开处理「不传props用默认值」和「传自定义props」两种场景,代码更直观,类型也完全符合预期:
interface Person { name: string; age: number; address: string; phone: string; } const defaultProps = ['name', 'age'] as const; // 重载1:不传props参数,返回默认属性集合 function pick(obj: Person): Pick<Person, typeof defaultProps[number]>; // 重载2:传自定义props参数,返回对应属性的Pick结果 function pick<T extends keyof Person>(obj: Person, props: ReadonlyArray<T>): Pick<Person, T>; // 实现签名,放宽类型兼容两种重载场景 function pick(obj: Person, props: ReadonlyArray<keyof Person> = defaultProps) { return props.reduce((res, prop) => { res[prop] = obj[prop]; return res; }, {} as any); // 此处断言不会影响外部调用类型,重载已经锁定了对外的返回类型 } // 测试用例 const testPerson: Person = { name: 'mitsos', age: 33, address: 'GRC', phone: '000' }; const result = pick(testPerson) // 类型为Pick<Person, "name" | "age">,符合预期 const result2 = pick(testPerson, ['phone']) // 类型为Pick<Person, "phone">,符合预期 const result3 = pick(testPerson, ['abc']) // 抛出类型错误,符合预期
内容的提问来源于stack exchange,提问作者mitsos1os
相关产品推荐
相关产品推荐

