【问题标题】:Typescript: How to use a generic parameter as object key打字稿:如何使用泛型参数作为对象键
【发布时间】:2019-10-18 13:09:14
【问题描述】:

是否可以编写一个接受字符串常量作为其参数之一的接口,并将其用作对象的键?

例如,假设我发出两个不同的 GraphQL 请求,它们都返回 User,但使用不同的键名:

const userByIdResult = {
  data: {
    userById: {
       id: 123,
       username: 'joseph'
    }
  }
}

const userByUsernameResult = {
  data: {
    userByUsername: {
       id: 123,
       username: 'joseph'
    }
  }
}

我想写一个通用接口会是这样的:

interface GraphQLResponse<QueryKey, ResponseType> {
  data: {
    [QueryKey]: ResponseType
  }
}

interface User {
    username: string
    id: string
}

type UserByIdResponse = GraphQLResponse<'userById', User>
type UserByUsernameResponse = GraphQLResponse<'userByUsername', User>

但是,this doesn't work

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    你已经接近了。这属于category of Mapped Types。您需要进行两处更改:

    1. QueryKey extends string
    2. key in QueryKey
    interface GraphQLResponse<QueryKey extends string, ResponseType> {
        data: {
            [key in QueryKey]: ResponseType;
        }
    }
    
    interface User {
        username: string;
        id: number;
    }
    
    type UserByIdResponse = GraphQLResponse<'userById', User>;
    type UserByUsernameResponse = GraphQLResponse<'userByUsername', User>;
    

    Example Usage

    const userByIdResult: UserByIdResponse = {
        data: {
            userById: {
                id: 123,
                username: 'joseph'
            }
        }
    }
    
    const userByUsernameResult: UserByUsernameResponse = {
        data: {
            userByUsername: {
                id: 123,
                username: 'joseph'
            }
        }
    }
    
    const userByIdResultBoom: UserByIdResponse = {
        data: {
            userByUsername: {
                id: 123,
                username: 'joseph'
            }
        }
    }
    

    【讨论】:

    • 感谢您的精彩解释!我对此完全感到困惑,因为[key in x] 听起来像是在循环遍历一个数组,所以我有点被抛出了。
    猜你喜欢
    • 2020-01-17
    • 2022-11-11
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    • 2021-05-21
    • 2021-06-17
    • 1970-01-01
    相关资源
    最近更新 更多