问一个typescript类型问题?

给定一条数据结构(API数组里面的个数是未知的)如下所示

const api = [
    {
        name: 'pageA',
        table: true
    },
    {
        name: 'pageB',
    }
]

如何推导出类似这样的类型

type Result = {
    pageA: boolean
    pageB: unknown
}

即 name 作为key, 如果存在table即为boolean类型,否则为unknown类型
ts的大神们,这个该如何写啊,百度,谷歌都折腾了,还问了gpt也不行,就是值推不出来
我写的是这样的

const api = [
    {
        name: 'pageList',
        table: true
    },
    {
        name: 'pageAdd',
        table: false
    }
] as const;

type Ret<T extends readonly { name: string; table?: boolean }[]> = {
    [K in T[number]['name']]:  // 这里不会写
};
type Api = Ret<typeof api>;
阅读 395
avatarAI BotBETA

你的问题在于如何为每个名字生成一个类型,如果对应的 table 属性为 true,则为 boolean 类型,否则为 unknown 类型。

在 TypeScript 中,你可以使用 keyof 和类型推断来解决这个问题。首先,你需要将 api 数组中的对象字面量转换为类型,然后你可以使用 keyof 来获取每个对象可能拥有的键的集合。最后,你可以使用类型推断和逻辑或操作符 | 来为每个键指定一个类型。

下面是你可以尝试的代码:

const api = [
    {
        name: 'pageA',
        table: true
    },
    {
        name: 'pageB',
    }
] as const;

type Result = {
    [K in keyof typeof api]: 
    typeof api[0][K] extends boolean ? K : never
    | K extends keyof typeof api[0] ? never : K
};

// 输出如下:
// type Result = {
//     pageA: "pageA" | never;
//     pageB: "pageB" | never;
// }

在这个类型中,我们首先使用 keyof typeof api 来获取所有可能的键的集合。然后,对于每一个键 K,我们检查该键在 api[0] 中是否存在并且是 boolean 类型。如果满足这个条件,那么我们就将该键的类型设置为 K。否则,我们就将该键的类型设置为 never。这样,我们就成功地为每个键生成了一个类型,如果该键在 api[0] 中存在并且是 boolean 类型,那么它的类型就是它的名字,否则它的类型就是 never

1 个回答
✓ 已被采纳
const api = [
  {
    name: 'pageList',
    table: true,
  },
  {
    name: 'pageAdd',
  },
] as const;

type Ret<T extends readonly {name: string; table?: boolean}[]> = {
  [K in T[number]['name']]: Extract<T[number], {name: K}> extends {
    table: boolean;
  }
    ? boolean
    : unknown;
};

type Api = Ret<typeof api>;
推荐问题
logo
Microsoft
子站问答
访问
宣传栏