Typescript 2 互相依赖的泛型类型

huangapple go评论56阅读模式
英文:

Typescript 2 Generic types dependent on each other

问题

我有两种类型的配置,一种用于身份验证,另一种用于一般配置,不包含任何秘密变量。我曾经有两个函数,但现在我尝试只使用一个函数,但我无法实现这段代码,出现了错误,我找不到我做错了什么。

interface Config {
    config: string;
    config_example: string;
} 

interface Auth {
    auth: string;
    auth_example: string;
}

type ConfigType = "auth" | "config";
type GetKeyType<C extends ConfigType> = C extends "auth" ? keyof Auth : C extends "config" ? keyof Config : never;

const auth: Auth = {
    auth: '',
    auth_example: ''
}

const config: Config = {
    config: '',
    config_example: ''
}

function getConfig<C extends ConfigType, K extends keyof GetKeyType<C>>(configType: C, key: K): GetKeyType<C>[K] {
    switch (configType) {
        case "auth":
            return auth[key];
        case "config":
            return config[key];
        default:
            throw new Error();
    }
}

这是你的代码,我已经将HTML实体转义字符(如&quot;)更改为双引号。你可以在 TypeScript Playground 上使用这个代码链接进行测试:[此处](https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgQexDYBzZBvAKGWNQy2wC5kBnMKUbAbiJPUxwH0IAPOAWwAOAGwhVa9EEwIBfZAQKhIsRCjgBXMAAt8LYuq1i6DZiWT7NXXoJGGJU6fLABPASjbkAKi5QBeZACJzf2QAHwD3HH9mZ1dkbAgwL1cAHgBhZB5IEAATalJ2bCSIAD5kP3TM
iBy8wI1NYIB+ZABrCCc0GDM65CoK7izc8LJI5CbW9s6I3CoQCAA3aGYCNlougzXtP0JTcyoAcj2AGl0Ny35hUWQDmXkVsHzyKimynVMp-aOTqbPrS+uHAgwNQgBBgYAYOIJVLDbDJE59AZ5KZFY6mADSGX6VUG4w6kMS3jSxQIxQAFO9kKlDi02lQ0QBKKjxAkpVLFADaaIAuq8SNQAO7AMAIbTkmH03mmYgIODUFC1LT+CgnKUkKAJNRQEAbdnjLkmVWoWXyqZKlWG9VgTXaqa6tr683EbIQeBqIRgZWGqVaKBofnIWb+gCiUF9UFJ9INxAcsiAA)。

如果你在IDE中添加//@ts-ignore来忽略错误,IDE会正确识别类型,但我理解你不想使用//@ts-ignore。这个代码看起来没有什么问题,如果你有特定的错误或问题,请提供更多细节,我将尽力帮助你找到解决方案。

英文:

I have two types of config one for auth and one for general config which doesn't have any secret variables I used to have two functions but now I'm trying to have only one function but I wasn't able to implement this code with errors, I couldn't find what I'm doing wrong

interface config {
    config: string;
    config_example: string;
} 

interface auth {
    auth: string;
    auth_example: string;
}

type configType = &quot;auth&quot; | &quot;config&quot;;
type getType&lt;C extends configType&gt; = C extends &quot;auth&quot; ? keyof auth : C extends &quot;config&quot; ? keyof config : never;

const auth: auth = {
    auth: &#39;&#39;,
    auth_example: &#39;&#39;
}

const config: config = {
    config: &#39;&#39;,
    config_example: &#39;&#39;
}

function getConfig&lt;
    C extends configType,
    K extends keyof getType&lt;C&gt;
&gt;(config: C, key: K): getType&lt;C&gt;[K] {
    switch (config) {
        case &quot;auth&quot;:
            return auth[key];
        case &quot;config&quot;:
            return config[key];
        default:
            throw new Error();
    }
} 

here's the typescipt playground code of this

If I put //@ts-ignore to the errors, the IDE correctly determines the types and everything but I don't want to implement this with //@ts-ignore I don't even know if this is possible to do that but any ideas?

答案1

得分: 1

请查看Wishlist: support for correlated union types #30581

const allConfigs = {
  "auth": auth,
  "config": config
}

function getConfig<
    CONFIG_NAME extends keyof typeof allConfigs,
    CONFIG_KEY extends keyof typeof allConfigs[CONFIG_NAME]
>(config: CONFIG_NAME, key: CONFIG_KEY): typeof allConfigs[config][key];

在TS Playground中查看代码

英文:

See Wishlist: support for correlated union types #30581

const allConfigs = {
  &quot;auth&quot;: auth,
  &quot;config&quot;: config
}

function getConfig&lt;
    CONFIG_NAME extends keyof typeof allConfigs,
    CONFIG_KEY extends keyof typeof allConfigs[CONFIG_NAME]
&gt;(config: CONFIG_NAME, key: CONFIG_KEY): typeof allConfigs[CONFIG_NAME][CONFIG_KEY] {
    return allConfigs[config][key];
} 

Code in TS Playground

huangapple
  • 本文由 发表于 2023年2月10日 03:14:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75403386.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定