typescript 使用constAssert,如何从嵌套对象中提取文字类型?

jfewjypa  于 2023-05-23  发布在  TypeScript
关注(0)|答案(1)|浏览(164)

假设我有以下对象:

const kids = {
  Karen: ['Ava', 'Emma'],
  Mary: ['Sophia'],
} as const;

通过使用constAssert,我可以提取文字类型:

type Mother = keyof typeof kids; // Karen|Mary
type Kid = typeof kids[Mother][number]; // Ava|Emma|Sophia

现在假设下面的对象,它是一个更深的层次:

const grandkids = {
  Karen: {
    Ava: ['Alice', 'Amelia'],
    Emma: ['Sarah'],
  },
  Mary: {
    Sophia: ['Grace'],
  },
} as const;

我可以提取第一层:

type Grandmother = keyof typeof grandkids; // Karen|Mary

但是如何提取Mother(Karen,玛丽)和Kid(Alice,Amelia,Sarah,Grace)的文字呢?

gab6jxml

gab6jxml1#

如果你真的只想提取每个字面值,你可以这样做:

const grandkids = {
  Karen: {
    Ava: ['Alice', 'Amelia'],
    Emma: ['Sarah'],
  },
  Mary: {
    Sophia: ['Grace'],
  },
} as const;

type Grandmother = keyof typeof grandkids;

type Mother = {
  [K in Grandmother]: keyof typeof grandkids[K];
}[Grandmother];

type Kid = {
  [K in Grandmother]: {
    [M in Mother]: typeof grandkids[K][M extends keyof typeof grandkids[K] ? M : never];
  };
}[Grandmother][Mother][number];

对于Mother,我们只需提取grandkids的每个属性的键
对于Kid,我们提取每个祖母内部的每个母亲的数组,并使用[number]将所有数组展平
这个条件

M extends keyof typeof grandkids[K] ? M : never

是重要的,因为此时M可以是'Karen'或'Mary'的键,所以typescript不允许我们使用M来索引grandkids[K],因为它不能确定Mgrandkids[K]的键。
希望这个能帮上忙

相关问题