是否可以根据 TypeScript 中 js 对象中定义的键来创建类型?

问题描述 投票:0回答:1

我还在学习 Typescript,所以我想知道是否有人可以帮助我解决这个问题。

我准备了一个简化的例子(在playground中打开):

interface SomeThing {
    a: string
    b: string
    c: string
}

const fields: Partial<Record<keyof SomeThing, boolean>> = {
  a: true,
  b: false,
}

type ExtractFields<T, F> = {
  [K in keyof F]-?: F[K] extends true ? K extends keyof T ? T[K] : never : never;
}

type Result = ExtractFields<SomeThing, typeof fields>

我的目标是

Result

type Result {
  a: string
}

相反,它会导致:

type Result = {
    a: never;
    b: never;
    c: never;
}

就像

F[K]
无法解析为
true
,即使在
true
中定义为
F[K] extends true

我向许多不同的人工智能寻求帮助,但似乎没有一个有用。

typescript typescript-typings
1个回答
0
投票

让我们逐步修复它。

首先让我们保留

fields
的类型:

const fields = {
  a: true,
  b: false,
} satisfies Partial<Record<keyof SomeThing, boolean>>

这给你:

type Result2 = {
    a: string;
}

这给了你预期

type Result = {
    a: string;
    b: never;
}

现在让我们改进

ExtractFields
以仅包含映射为 true 的键。

type ExtractFields2<T, F> = {
  [K in keyof F as F[K] extends true? K : never]-?: K extends keyof T ? T[K] : never;
}
type Result2 = ExtractFields2<SomeThing, typeof fields>

完整代码:

interface SomeThing {
    a: string
    b: string
    c: string
}

const fields = {
  a: true,
  b: false,
} satisfies Partial<Record<keyof SomeThing, boolean>>

type ExtractFields<T, F> = {
  [K in keyof F]-?: F[K] extends true ? K extends keyof T ? T[K] : never : never;
}

type Result = ExtractFields<SomeThing, typeof fields>


type ExtractFields2<T, F> = {
  [K in keyof F as F[K] extends true? K : never]-?: K extends keyof T ? T[K] : never;
}
type Result2 = ExtractFields2<SomeThing, typeof fields>
© www.soinside.com 2019 - 2024. All rights reserved.