TypeScript函数类型不匹配报错求助:resolveOrientation类型分配问题
解决TypeScript泛型函数返回类型不匹配报错TS2322
错误信息
src/helpers.ts:11:14 - error TS2322: Type '<T extends "horizontal" | "vertical" | undefined, U extends AriaRole | undefined>(ariaOrientation: T, role: U) => "horizontal" | "vertical" | NonNullable<T> | "both"' is not assignable to type 'ResolveOrientationFunction'. Type '"horizontal" | "vertical" | NonNullable<T> | "both"' is not assignable to type 'NonNullable<T> | "both"'. Type '"horizontal"' is not assignable to type 'NonNullable<T> | "both"'.
原代码
import { type HTMLAttributes } from "react"; type ResolveOrientationFunction = < T extends HTMLAttributes<HTMLElement>["aria-orientation"], U extends HTMLAttributes<HTMLElement>["role"] >( ariaOrientation: T, role: U ) => "both" | NonNullable<T>; export const resolveOrientation: ResolveOrientationFunction = (ariaOrientation, role) => { if (ariaOrientation === undefined) { switch (role) { case "menubar": case "slider": case "tablist": case "toolbar": { return "horizontal"; } case "listbox": case "menu": case "scrollbar": case "tree": { return "vertical"; } } } return ariaOrientation ?? "both"; };
错误原因
泛型定义的返回类型"both" | NonNullable<T>存在约束矛盾:
- 当
T被推断为undefined时,NonNullable<T>等于never,此时返回类型被收缩为"both" - 但函数在
ariaOrientation为undefined时,实际返回了"horizontal"或"vertical",这两个值不在"both"类型范围内,导致类型不匹配
解决方案
方案1:使用条件类型适配泛型返回
修改ResolveOrientationFunction的返回类型,根据T是否为undefined动态调整允许的返回值:
import { type HTMLAttributes } from "react"; type ResolveOrientationFunction = < T extends HTMLAttributes<HTMLElement>["aria-orientation"], U extends HTMLAttributes<HTMLElement>["role"] >( ariaOrientation: T, role: U ) => T extends undefined ? "both" | "horizontal" | "vertical" : "both" | NonNullable<T>; export const resolveOrientation: ResolveOrientationFunction = (ariaOrientation, role) => { if (ariaOrientation === undefined) { switch (role) { case "menubar": case "slider": case "tablist": case "toolbar": { return "horizontal"; } case "listbox": case "menu": case "scrollbar": case "tree": { return "vertical"; } } } return ariaOrientation ?? "both"; };
这种方案保留了泛型的类型推断能力:当传入明确的"horizontal"或"vertical"时,函数返回类型会精确到对应值+"both";当传入undefined时,返回所有可能的方向值+"both"。
方案2:简化类型定义(放弃泛型精确推断)
如果不需要泛型带来的精确类型推断,可以直接定义固定的输入输出类型,代码更简洁:
import { type HTMLAttributes } from "react"; type Orientation = NonNullable<HTMLAttributes<HTMLElement>["aria-orientation"]>; type ResolveOrientationFunction = ( ariaOrientation: Orientation | undefined, role: HTMLAttributes<HTMLElement>["role"] ) => "both" | Orientation; export const resolveOrientation: ResolveOrientationFunction = (ariaOrientation, role) => { if (ariaOrientation === undefined) { switch (role) { case "menubar": case "slider": case "tablist": case "toolbar": { return "horizontal"; } case "listbox": case "menu": case "scrollbar": case "tree": { return "vertical"; } } } return ariaOrientation ?? "both"; };
这种方案直接明确函数返回"both" | "horizontal" | "vertical",完全符合你的预期返回类型,同时避免了泛型约束带来的冲突。
内容的提问来源于stack exchange,提问作者devatina11yb
相关产品推荐
相关产品推荐

