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

TypeScript如何根据输入参数定义字面量类型实现createContext?

问题:实现动态键名的createContext函数并让TypeScript正确识别

我想实现一个createContext函数,返回对象的键名基于输入参数的名称前缀,希望TypeScript能识别返回值的键由输入参数决定。尝试了以下代码:

export function createContext<Name extends string = string>(
  name: Name,
): {
  [`use${name}Context`]: any;
  [`${name}Provider`]: any;
};

export function createContext(name:string){
    return {
        [`use${name}Context`]:0,
        [`${name}Provider`]:0
    }
}

但遇到了错误:

A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.(1170)

想问这是不是意味着没法实现需求?


错误原因

TypeScript禁止在类型字面量中使用泛型变量作为计算属性名,因为你定义的Name是string的子类型,但不属于字面量类型或unique symbol类型,不符合类型字面量对计算属性名的要求。

解决方案

使用映射类型结合Template Literal Types来生成动态键名,就能绕过这个限制:

export function createContext<Name extends string>(
  name: Name,
): {
  [K in `use${Name}Context` | `${Name}Provider`]: any;
};

export function createContext(name: string) {
  return {
    [`use${name}Context`]: 0,
    [`${name}Provider`]: 0,
  };
}

修改后,当你传入具体的字面量参数(比如createContext('Auth')),TypeScript会自动推断返回类型为{ useAuthContext: any; AuthProvider: any; },完全符合需求。

可选优化:泛型化上下文值

如果需要更精准的类型,可以给上下文值添加泛型,让返回的Hook和Provider类型更贴合实际场景:

import React from 'react';

export function createContext<Name extends string, T = unknown>(
  name: Name,
  defaultValue?: T,
): {
  [K in `use${Name}Context`]: () => T;
} & {
  [K in `${Name}Provider`]: React.Provider<T>;
};

export function createContext(name: string, defaultValue?: unknown) {
  const context = React.createContext(defaultValue);
  return {
    [`use${name}Context`]: () => React.useContext(context),
    [`${name}Provider`]: context.Provider,
  };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:00:58