能否根据参数属性改变TypeScript函数的返回类型?
实现根据参数属性动态改变返回类型的querySelector封装
你的需求完全可行,TypeScript支持通过函数重载或条件类型实现根据参数属性调整返回类型的逻辑,下面是两种具体的解决方案:
方案一:函数重载(推荐,直观易维护)
通过定义多个函数签名,明确不同参数组合对应的返回类型:
type QuerySelectorOptions = { required?: boolean; }; // 重载1:当传入required: true时,返回确定的T类型 function querySelector<T extends HTMLElement>( selector: string, options: QuerySelectorOptions & { required: true } ): T; // 重载2:不传options或required为false时,返回T | null function querySelector<T extends HTMLElement>( selector: string, options?: QuerySelectorOptions ): T | null; // 函数实现(返回类型由重载签名自动推断) function querySelector<T extends HTMLElement>( selector: string, options: QuerySelectorOptions = {} ) { const element = document.querySelector<T>(selector); if (options.required && !element) { throw new ReferenceError(`Can't find an element that matches "${selector}"`); } return element; }
使用效果
// 自动推断foo类型为HTMLElement,无null警告 const foo = querySelector(".foo", { required: true }); foo.addEventListener("click", () => {}); // bar类型为HTMLElement | null,需做null校验 const bar = querySelector(".bar"); if (bar) { bar.addEventListener("click", () => {}); }
方案二:条件类型结合泛型
通过泛型捕获required的布尔值,用条件类型动态生成返回类型:
type QuerySelectorOptions<R extends boolean = false> = { required?: R; }; function querySelector<T extends HTMLElement, R extends boolean = false>( selector: string, options: QuerySelectorOptions<R> = {} as QuerySelectorOptions<R> ): R extends true ? T : T | null { const element = document.querySelector<T>(selector); if (options.required && !element) { throw new ReferenceError(`Can't find an element that matches "${selector}"`); } // 此处需要类型断言,因为TS无法自动推断条件类型的返回值 return element as R extends true ? T : T | null; }
为什么你的之前尝试失败?
- 泛型参数
O extends QuerySelectorOptions的问题:TS无法确定O['required']的具体值,且默认值{}无法适配所有可能的O子类型,导致类型不兼容报错。 - 直接引用
options.required作为返回类型:返回类型是编译时概念,无法直接关联运行时的参数属性,因此会提示找不到options命名空间。
内容的提问来源于stack exchange,提问作者James Long
相关产品推荐
相关产品推荐

