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

如何在TypeScript中推断对象字面量类型且避免readonly修饰符

如何让TypeScript泛型推断字面量类型且不带readonly修饰符

问题需求

需要将对象的所有属性推断为字面量类型,但不希望生成的类型带有readonly属性,主要用于优化IntelliSense体验,减少复杂结构的视觉负担。

基础问题示例

type Options = {
  min?: number;
};

class E1<O extends Options> {
  constructor(options: O) {}
}

const e1 = new E1({ min: 1 });

此时typeof e1的结果不符合期望:

E1<{
    min: number; // 期望是`1`而非number
}>

使用const类型参数的尝试

TypeScript 5.0的const类型参数能实现字面量推断,但会自动添加readonly修饰符:

class E2<const O extends Options> {
  constructor(options: O) {}
}

const e2 = new E2({ min: 1 });

typeof e2的结果:

E2<{
    readonly min: 1; // 类型正确但带有readonly
}>

期望的最终结果

EN<{
   min: 1; 
}>

无效的尝试方案

方案一:构造函数参数移除readonly

试图在构造函数参数中映射移除readonly,但泛型仍保留readonly属性:

class E3<const C extends Options> {
  constructor(c: { -readonly [K in keyof C]: C[K] }) {}
}

const e3 = new E3({ min: 1 });

方案二:通过类型工具约束泛型

定义移除readonly的类型工具,但泛型推断结果依旧带有readonly:

type NoRead<T> = {
  -readonly [K in keyof T]: T[K];
};

class E4<const C extends NoRead<Options>> {
  constructor(c: C) {}
}

const e4 = new E4({ min: 1 });

可行但繁琐的方案

对单个属性添加as const断言能得到期望类型,但对象结构复杂时操作繁琐:

class E5<C extends Options> {
  constructor(c: C) {}
}

const e5 = new E5({ min: 1 as const });

解决方案:工厂函数+类型转换

通过工厂函数利用const参数推断字面量,再将类型转换为不带readonly的版本:

type Options = {
  min?: number;
};

// 移除readonly的类型工具
type Writable<T> = { -readonly [K in keyof T]: T[K] };

class EN<O extends Options> {
  constructor(options: O) {}
}

// 工厂函数:用const参数推断字面量,再转换为可写类型
function createEN<const O extends Options>(options: O): EN<Writable<O>> {
  return new EN(options);
}

// 测试
const en = createEN({ min: 1 });
// typeof en: EN<{ min: 1 }>

或者直接在类的泛型中处理(适合直接实例化的场景):

type Options = {
  min?: number;
};

type Writable<T> = { -readonly [K in keyof T]: T[K] };

class EN<O extends Options> {
  constructor(options: O extends infer U ? Writable<U> : never) {}
}

const en = new EN({ min: 1 });
// typeof en: EN<{ min: 1 }>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 05:33:18