使用 TypeScript 对带有前缀的 JSON 文件键的类型定义
Posted
技术标签:
【中文标题】使用 TypeScript 对带有前缀的 JSON 文件键的类型定义【英文标题】:Type Definition for JSON file Keys with Prefix using TypeScript 【发布时间】:2021-07-26 02:27:28 【问题描述】:我正在将 JSON 文件导入到我的 TypeScript 程序中,如下所示:(我在 tsconfig.json
中启用了 resolveJsonModule
)
import data from './sample.json';
很高兴,我注意到从 JSON 文件接收到的对象是强类型的。然后我编写了一个函数,该函数根据参数访问所述 JSON 对象的某个键:
export const get = (key: keyof typeof data): void =>
console.log(data[key]); // example code
;
这按预期工作,我的函数的使用者会知道 JSON 文件中接受/包含哪些值。问题来了:我希望我的函数的使用者只能访问我前缀的某些键(在以下示例中,前缀是 prefix_
):
export const get = (key: keyof typeof data): void =>
console.log(data[`prefix_$key`]);
;
我必须如何更改我的类型定义才能使其仍然有效?
【问题讨论】:
【参考方案1】:TypeScript 4.3 之前
从 TypeScript 4.2 开始,无法在使用字符串函数的情况下执行条件类型,因此我不知道如何指定以前缀开头的键。
我能想到的最好的方法是使用 Pick utility type 从所有可能属性的交集和 json 文件的派生类型创建一个新类型。
在下面的示例中,我导入了两个示例 json 文件。接下来,我指定所有可能的键以保留在字符串文字类型中。然后使用 Pick 从这两个文件中创建两种类型。为了让 Pick 工作,我必须在第二个参数中传递一个类型,它是派生文件类型和 PublicPrefix 类型的键的交集。
import data1 from './sample1.json'; // x: 1, prefix_A: 2, prefix_B: 3
import data2 from './sample2.json'; // y: 1, prefix_B: 2, prefix_C: 3
type PublicPrefix = 'prefix_A' | 'prefix_B' | 'prefix_C';
export type Data1 = Pick<typeof data1, keyof typeof data1 & PublicPrefix>;
// Data1 = prefix_A: number, prefix_B: number
export type Data2 = Pick<typeof data2, keyof typeof data2 & PublicPrefix>;
// Data2 = prefix_B: number, prefix_C: number
如果 data1 具有属性 prefix_A 和 prefix_B,而 data2 具有属性 prefix_B 和 prefix_C,则结果类型将是 Data1 = prefix_A, prefix_B
和 Data2 = prefix_B, prefix_C
,所有其他键都被排除在外。
TypeScript 4.3 中的模板字符串文字
TypeScript 4 引入了模板字符串文字,在 4.3 版中,它们增强了功能,因此您可以指定上下文类型的模板。这允许您在模板中指定一个类型,将模板的这些部分扩展为对该类型有效的任何内容。
在下面的示例中,创建了一个模板字符串文字,它以 prefix_ 开头,后跟任何字符串。通过以与上例相同的方式使用 Pick,生成的类型将仅包含以 prefix_ 开头的属性。
import data from './sample.json';
type PublicPrefix = `prefix_$string`;
export type Data1 = Pick<typeof data, keyof typeof data & PublicPrefix>;
【讨论】:
以上是关于使用 TypeScript 对带有前缀的 JSON 文件键的类型定义的主要内容,如果未能解决你的问题,请参考以下文章
带有 TypeScript 解析器/插件的 ESLint:如何包含从 tsconfig.json 中排除的 .spec.ts?