将 Typescript Record 或类似字典的类型与固定键类型合并? [英] Merge Typescript Record or dictionary-like type with fixed key typings?

查看:39
本文介绍了将 Typescript Record 或类似字典的类型与固定键类型合并?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法扩展内置的 Record(或一个 { [key:string]: string } 接口),你还定义了一些固定的键和它们的类型?

Is there a way to extend the built-in Record (or a { [key:string]: string } interface) where you also define some fixed keys and their types?

假设我们有这个:

const otherValues = {
    some: 'some',
    other: 'other',
    values: 'values',
}

const composedDictionary = {
    id: 1,
    ...otherValues
}

我想为composedDictionary 定义一个接口,其中id 被输入为number(并且只有数字),其他的一切都是string.

I want to define an interface for composedDictionary where id is typed as number (and number only) and everything else as string.

我已经试过了:

interface ExtendedRecord extends Record<string, string> {
    id: number;
}

还有这个:

interface MyDictionary {
    [key: string]: string;
    id: number;
}

两者都失败:

'number' 类型的属性 'id' 不能分配给字符串索引类型 'string'

有什么想法吗?

推荐答案

理想情况下,索引签名应该反映任何可能的索引操作结果.如果您使用不可检查的字符串键访问 composedDictionary,结果可能是 number 如果 string 实际上是 'id'(例如:composedDictionary['id' as string],打字会说这是string,但在运行时结果是number).这就是类型系统在此问题上与您争论的原因,这是一种不一致的类型.

Ideally the index signature should reflect any possible indexing operation result. If you access composedDictionary with an uncheckable string key the result might be number if that string is actually 'id' (eg: composedDictionary['id' as string], the typings would say this is string but at runtime it turns out to be number). This is why the type system is fighting you on this, this is an inconsistent type.

您可以将索引定义为与所有属性保持一致:

You can define your index to be consistent will all properties:

interface MyDictionary {
    [key: string]: string | number;
    id: number;
}

打字稿对索引和属性一致性的检查存在漏洞.该漏洞是交叉类型:

There is a loophole to the checks typescript does for index and property consistency. That loop hole is intersection types:

type MyDictionary  = Record<string, string> & {
  id: number
}


const composedDictionary: MyDictionary = Object.assign({
    id: 1,
}, {
    ...otherValues
});

编译器仍然会在赋值时与你争吵,在类型系统中创建这种不一致对象的唯一方法是使用 Object.assign

The compiler will still fight you on assignment, and the only way to create such an inconsistent object in the type system is by using Object.assign

这篇关于将 Typescript Record 或类似字典的类型与固定键类型合并?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆