根据同一对象中的键缩小属性的可能值

  • 本文关键字:属性 缩小 对象 typescript
  • 更新时间 :
  • 英文 :


我有以下结构:

export interface AppConfig {
encryptionKey: string;
db: TypeOrmModuleOptions;
}
export interface BrandsConfig {
/**
* Brand name
*/
[key: string]: AppConfig;
}
export interface IConfig {
brands: BrandsConfig;
master: string;
}
export class Config implements IConfig {
public readonly brands: BrandsConfig;
public readonly master: string;
public constructor(init: IConfig) {
Object.assign(this, init);
}
}

这个想法是 BrandsConfig 是一个键/值集合,其中值是此命名实例的设置。同时,"master"应该赋予其中一个(并且只有一个(实例一个特殊地位。

有什么方法可以静态限制"master"的可能值(至少在 Config 类中,理想情况下也在接口中(,以便它们不仅仅是任何字符串,而是 BrandConfig 键中的字符串?我知道我可以在运行时在构造函数中进行此检查,但我正在尝试将尽可能多的检查移动到编译阶段,并为它提供适当的智能感知。

您可以使用泛型和 keyof/Index Type Query 运算符来执行此操作。

1.( 将泛型类型参数B添加到您的 Config 类中,该参数可分配给/扩展 BrandConfig:

export class Config<B extends BrandsConfig> implements IConfig<B> {
public readonly brands: B;
public readonly master: keyof B;
public constructor(init: IConfig<B>) {
// Make it compile. Feel free to replace it by delegates, getters,etc.
this.brands = init.brands;
this.master = init.master;
}
}

2.( 还要在IConfig中添加相应的泛型类型参数,这样我们就可以将 master 定义为依赖于 BrandsConfig 中键的键:

export interface IConfig<B extends BrandsConfig> {
brands: B;
master: keyof B;
}

让我们测试客户端。在这里,如果我们传入错误的密钥,我们预计会出现错误master.

const myConfig = {
brands: {
brand1: { encryptionKey: "", db: {} },
brand2: { encryptionKey: "", db: {} }
},
master: "brand1"
} as const
const config = new Config(myConfig); // works!

现在将您的主属性更改为master: "Wanna be a brand",然后您将获得:

类型"想成为品牌"不能分配给类型"品牌1" |"品牌2"'。

另请注意,我们使用 const 断言来缩小推断的myConfig类型。

操场

最新更新