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

TypeScript中如何实例化仅接受原始类型的泛型类型/接口

问题原因说明

  1. 第一种简单泛型实现返回字面量类型,是因为TypeScript默认会将传入的字面量参数的泛型参数推导为字面量类型,而非string/number/boolean这类宽原始类型,导致后续同类型普通值无法赋值。
  2. 条件类型写法的报错是TypeScript的类型系统限制:当条件类型依赖未被具体值实例化的泛型参数时,编译器不会提前推导条件类型的最终结果,所以无法确认T和AP<T>的类型兼容性,哪怕逻辑上二者是完全对应的。

可行实现方案

方案1:函数重载实现(最优雅,无类型断言)

通过函数重载分别限定三种原始类型的入参和返回值类型,实现签名只需兼容所有重载即可,完全不需要类型断言:

type Primitive = number | string | boolean;

interface MyInterface<T extends Primitive> {
    value: T;
}

// 重载签名
function createMyInterface(value: string): MyInterface<string>;
function createMyInterface(value: number): MyInterface<number>;
function createMyInterface(value: boolean): MyInterface<boolean>;
// 实现签名
function createMyInterface(value: Primitive): MyInterface<Primitive> {
    return { value };
}

// 测试代码
const x = createMyInterface("someString"); // 类型为 MyInterface<string>
x.value = "foo"; // 可正常赋值,无报错
const y = createMyInterface(42); // 类型为 MyInterface<number>
const z = createMyInterface(true); // 类型为 MyInterface<boolean>

如果需要单独的createPrimitive函数,也可以用同样的重载写法:

function createPrimitive(value: string): string;
function createPrimitive(value: number): number;
function createPrimitive(value: boolean): boolean;
function createPrimitive(value: Primitive) {
    return value;
}

let a = createPrimitive("someString"); // 类型为 string
a = "foo"; // 可正常赋值

方案2:条件类型+安全类型断言

如果你不想写多份重载,可以保留你现有的条件类型定义,仅在返回值处做逻辑可证的安全类型断言,不需要断言为any:

type Primitive = number | string | boolean;
type AP<T extends Primitive> = T extends string ? string : T extends number ? number : boolean;

interface MyInterface<T extends Primitive> {
    value: T;
}

function createMyInterface<T extends Primitive>(value: T): MyInterface<AP<T>> {
    return { value: value as AP<T> };
}

function createPrimitive<T extends Primitive>(v: T): AP<T> {
    return v as AP<T>;
}

该方案的类型安全性和重载方案一致,因为你可以完全确定T和AP<T>的类型是兼容的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:36:03