首页 > 解决方案 > 当父键是通用的时限制子接口的有效键

问题描述

当使用通用键扩展父级时,有没有办法让子类型具有一组受限的有效键?例如:

class SomeClass {
  constructor(public value: number) {}
}

interface IParent {
  [key: string]: SomeClass;
}

interface IChild extends IParent {
  a: SomeClass;
  b: SomeClass;
}

const o: IChild = {
  a: new SomeClass(1),
  b: new SomeClass(2),
  c: new SomeClass(3) // I'd like this to be an error
};

我希望任何扩展IParent都被强制SomeClass为所有键值,但理想情况下,分配任何不是在IChild's 接口中明确列出的键的东西都会导致错误。

这可能吗?

标签: typescript

解决方案


您可以只使用映射类型:

type ValidKeys = 'a' | 'b';
type IParent = { [key in ValidKeys]: SomeClass };

interface IChild extends IParent { } // You don't really need this interface.

const o: IChild = {
  a: new SomeClass(1),
  b: new SomeClass(2),
  c: new SomeClass(3),
  // Object literal may only specify known properties, and 'c' does not exist in type 'IChild'.
};

但请注意,这只会保护您免于声明IChild具有无效属性的文字。这仍然是完全有效的:

const m = {
  a: new SomeClass(1),
  b: new SomeClass(2),
  c: new SomeClass(3),
};

const o: IChild = m;

你也可以使IParent泛型能够有多个孩子,

type IParent<T extends string> = { [key in T]: SomeClass };

type IHasAB = IParent<'a' | 'b'>;
type IHasXY = IParent<'x' | 'y'>;

const ab: IHasAB = {
    a: new SomeClass(1),
    b: new SomeClass(2),
};
const xy: IHasXY = {
    x: new SomeClass(3),
    y: new SomeClass(4),
};

推荐阅读