关于TS类型推导中结果中,函数参数的类型问题?

关于TS类型推导中结果中,函数参数的类型问题?

链接在这里:https://tsplay.dev/mxE51W

type ClassNamesUtil = (value: string) => string;
type ClassNames = (value: number) => string;

interface WraperProps<T extends string | undefined = undefined> {
    styles: T;
    cx: T extends string ? ClassNamesUtil : ClassNames;
}

function action<T extends string | undefined = undefined>({ styles, cx }: WraperProps<T>) {

    
    console.log(styles, cx('a'));
}

问题是:

  1. 为什么在action中,调用cx('a')的时候,参数类型是never呢?
  2. 如何让cx根据传入的泛型T来决定接受的类型呢?

281707912317_.pic.jpg

阅读 1.9k
avatarAI BotBETA
  1. 为什么在action中,调用cx('a')的时候,参数类型是never呢?

在 TypeScript 中,never 类型表示一个值永远不会出现。在你的代码中,cx 的类型取决于 styles 的类型。如果 styles 是一个字符串,那么 cx 应该是 ClassNamesUtil 类型;如果 styles 不是字符串,那么 cx 应该是 ClassNames 类型。

然而,你的 action 函数没有明确的 T 类型参数。因此,当你在 action 函数内部调用 cx('a') 时,TypeScript 无法确定 T 的具体类型,所以它不知道 cx 的具体类型。因此,它不能推断出 cx('a') 的类型。由于没有明确的类型信息,TypeScript 将 cx('a') 的类型推断为 never

  1. 如何让cx根据传入的泛型T来决定接受的类型呢?

要解决这个问题,你需要明确指定 T 的类型。你可以通过在调用 action 函数时传递一个类型参数来实现这一点。例如:

action<string>({ styles: 'myStyle', cx: classNamesUtil });

在这个例子中,我们明确指定了 T 的类型为字符串,因此 TypeScript 可以推断出 cx 的类型为 ClassNamesUtil。然后,你可以在 cx('a') 中使用字符串类型的参数,而不会出现类型错误。

1 个回答

Tundefined 时,WraperProps 为:

interface WraperProps {
    styles: undefined
    cx: (value: number) => string
}

函数调用 cx('a') 非法

cxClassNamesUtil | ClassNames
==> ((value: string) => string) | ((value: number) => string)
==> (value: string & number) => (string | string)
==> (value: never) => string

尝试使用函数重载和 any

function action(arg: { styles: string, cx: (v: string) => string }): void;
function action(arg: { cx: (v: number) => string }): void;

function action({ styles, cx }: { styles?: string, cx: (v: any) => string }) { }
logo
Microsoft
子站问答
访问
宣传栏