如何为返回全必填/全可选对象的函数标注返回类型?
TypeScript中函数根据条件返回全必填/全可选对象的类型标注方案
问题场景
当函数需要根据条件返回某接口的全必填对象或全可选对象时,如何优雅地标注返回类型并确保分支内的类型校验?
示例代码
interface Test { x?: number; y?: number; } const testFunction = (isTrue: boolean): Test => { if (isTrue) { return { // 此处需强制返回Test的所有属性 x: 1, y: 1, } } return { x: 1 } }
现有实现方案
通过自定义MarkRequired类型强制校验全必填分支,但需要额外创建变量:
type MarkRequired<T extends object, Keys extends keyof T> = Omit<T, Keys> & Required<Pick<T, Keys>>; const testFunction = (isTrue: boolean): Test => { if (isTrue) { const data: MarkRequired<Test, keyof Test> = { x: 1, y: 1, } return data } return { x: 1 } }
更优雅的实现方案
方案1:直接返回联合类型
将函数返回类型设置为Required<Test> | Test,TypeScript会自动在对应分支校验类型:
interface Test { x?: number; y?: number; } const testFunction = (isTrue: boolean): Required<Test> | Test => { if (isTrue) { // 此处必须返回所有属性,否则TS会报错 return { x: 1, y: 1, }; } return { x: 1 }; };
方案2:函数重载(推荐,类型推断更精确)
通过函数重载声明不同入参对应的返回类型,调用方可以获得更精准的类型提示:
interface Test { x?: number; y?: number; } // 重载声明:明确不同参数对应的返回类型 function testFunction(isTrue: true): Required<Test>; function testFunction(isTrue: false): Test; function testFunction(isTrue: boolean): Required<Test> | Test; // 函数实现 function testFunction(isTrue: boolean) { if (isTrue) { return { x: 1, y: 1, }; } return { x: 1 }; } // 调用时自动推断类型 const fullObj = testFunction(true); // 类型为Required<Test>,可直接访问x、y const partialObj = testFunction(false); // 类型为Test,x、y仍为可选属性
方案3:类型断言简化现有方案
不需要额外变量,直接在return语句中使用类型断言:
interface Test { x?: number; y?: number; } type MarkRequired<T extends object, Keys extends keyof T> = Omit<T, Keys> & Required<Pick<T, Keys>>; const testFunction = (isTrue: boolean): Test => { if (isTrue) { return { x: 1, y: 1, } as MarkRequired<Test, keyof Test>; } return { x: 1 }; };
内容的提问来源于stack exchange,提问作者bazmexes
相关产品推荐
相关产品推荐

