如何在JSDoc中保留字面量类型信息且无需显式声明类型?
如何在JSDoc中无需手动拼写类型保留字面量类型信息(保留
as const特性) 我有如下代码片段,想请教如何在不手动拼写类型的前提下,保留knowLiteral的字面量类型信息?我使用的是JSDoc,同时希望完整保留as const的类型特性。
// @ts-check /** * @typedef {Readonly<Record<string, string>>} ReadonlyStringRecord */ /** * @template {ReadonlyStringRecord} T */ class Main { /** * @param {T} knowLiteral */ constructor(knowLiteral) { /** * @readonly * @type {T} */ this.knowLiteral = knowLiteral; } } // 不想手动写这部分类型 /** * @extends {Main<{ * this_is_know: '42' * }>} */ class Main2 extends Main { constructor() { const knowLiteral = /** @type {const} */ ({ 'this_is_know': '42' }); super(knowLiteral); } testFunc() { // 这里应该(目前也确实)报错 let x = this.knowLiteral.this_is_not_defined; } }
解决方案
无需手动重复编写泛型类型,让TypeScript自动推导父类泛型参数即可,同时保留as const的字面量约束效果。修改后的代码如下:
// @ts-check /** * @typedef {Readonly<Record<string, string>>} ReadonlyStringRecord */ /** * @template {ReadonlyStringRecord} T */ class Main { /** * @param {T} knowLiteral */ constructor(knowLiteral) { /** * @readonly * @type {T} */ this.knowLiteral = knowLiteral; } } // 移除手动泛型声明,让TS自动推导 class Main2 extends Main { constructor() { // 用TS原生的as const断言,JSDoc环境同样支持 const knowLiteral = ({ 'this_is_know': '42' }) as const; super(knowLiteral); } testFunc() { // 依然会报错,符合预期 let x = this.knowLiteral.this_is_not_defined; } }
核心说明
- 删掉子类的
@extends {Main<...>}手动泛型定义,TypeScript会根据super()传入的as const断言对象,自动推导父类泛型T的精确字面量类型。 - 如果偏好纯JSDoc写法,也可以保留
/** @type {const} */断言,效果完全一致:constructor() { const knowLiteral = /** @type {const} */ ({ 'this_is_know': '42' }); super(knowLiteral); } - 最终
this.knowLiteral会保持{ readonly this_is_know: "42" }的精确类型,访问不存在的属性时正常报错,同时不需要手动重复编写类型代码。
内容的提问来源于stack exchange,提问作者tovernaar123
相关产品推荐
相关产品推荐

