第 78 期 - TypeScript 5.4's NoInfer Utility Type
摘要
介绍 TypeScript 5.4 中的 NoInfer 实用类型,包括如何使用它控制泛型函数中的类型推断,还通过实例展示了避免类型推断错误的情况。
1. NoInfer 的基本概念
在 TypeScript 5.4 中引入了一个新的实用类型 NoInfer。它可以用来阻止 TypeScript 从泛型函数内部推断类型。例如,有一个泛型函数const returnWhatIPassedIn = <T>(value: T) => value;
,当传入"hello"
时,TypeScript 会推断出结果result
的类型为"hello"
。但是如果将value: T
改为value: NoInfer<T>
,再次传入"hello"
时,result
就会被推断为unknown
,此时需要显式提供类型给returnWhatIPassedIn
才能得到期望的返回类型,如const result = returnWhatIPassedIn<"hello">("hello");
。
2. 使用场景
2.1 有限状态机示例
- 以创建有限状态机(FSM)的函数为例,函数签名为
declare function createFSM<TState extends string>(config: { initial: TState; states: TState[]; }): TState;
。这里有两个地方(initial
和states
)可能被 TypeScript 用来推断TState
类型。 - 当调用这个函数时,如
const example = createFSM({ initial: "not - allowed", states: ["open", "closed"] });
,TypeScript 会从initial
和states
两者推断TState
,结果example
的类型为"not - allowed" | "open" | "closed"
,但这可能会有问题。 - 我们希望 TypeScript 只从
states
推断TState
,不让initial
成为推断的候选。这时可以使用 NoInfer,将函数签名改为declare function createFSM<TState extends string>(config: { initial: NoInfer<TState>; states: TState[]; }): TState;
,再次调用时,TypeScript 就只会从states
推断TState
,如果initial
的值不在states
数组中就会报错。
2.2 切换 NoInfer 的位置
- 如果将 NoInfer 应用到
states
上,如declare function createFSM<TState extends string>(config: { initial: TState; states: NoInfer<TState>[]; }): TState;
。 - 当调用
createFSM
时,只有initial
的值才是有效的状态,否则会报错,如createFSM({ initial: "open", states: ["closed"] });
会因为"closed"
类型与"open"
不匹配而报错。
3. 总结
NoInfer 可以用于控制 TypeScript 从泛型函数内部的何处推断类型,在有多个运行时参数引用相同类型参数时非常有用。
扩展阅读
Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有