You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript多类型参数:仅传首个参数并保留类型推断的更优实现

解决方案

方案1:利用TypeScript 4.7+的部分类型参数推断

给第二个类型参数N设置默认值,这样可以只显式指定T,让N自动从传入的name参数推断:

function createMyContext<T, N extends Capitalize<string> = unknown>(name: N) {
  const contextName = `${name}Provider` as const;
  const hookName = `use${name}` as const;
  // 省略Context创建的运行时逻辑
  return {
    [contextName]: {},
    [hookName]: () => ({})
  } as {[K in typeof contextName]: Provider<T>} & {[K in typeof hookName]: () => T};
}

调用方式:

const {UserProvider, useUser} = createMyContext<User>("User");

原理

  • TypeScript 4.7及以上支持部分类型参数推断,当你给某个类型参数设置默认值后,显式指定其他参数时,未指定的参数会自动推断
  • N extends Capitalize<string>确保传入的name首字母大写,符合Provider和Hook的命名规范

方案2:兼容旧版TypeScript的对象参数写法

如果你的项目还在使用TypeScript 4.6及以下版本,可以用对象参数的方式,虽然多了一层对象,但比双重调用更直观:

function createMyContext<T, N extends Capitalize<string>>(options: { name: N }) {
  const contextName = `${options.name}Provider` as const;
  const hookName = `use${options.name}` as const;
  // 省略运行时逻辑
  return {
    [contextName]: {},
    [hookName]: () => ({})
  } as {[K in typeof contextName]: Provider<T>} & {[K in typeof hookName]: () => T};
}

调用方式:

const {UserProvider, useUser} = createMyContext<User>({ name: "User" });

内容的提问来源于stack exchange,提问作者asnaeb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 09:59:52