【问题标题】:TypeScript: Return type has all keys specified as parameterTypeScript:返回类型将所有键指定为参数
【发布时间】:2018-07-06 19:49:51
【问题描述】:

我想以某种方式键入一个函数,返回类型将是一个对象,它包含数组中指定的键作为参数。这些键也应该都是特定的枚举类型。我已经尝试了几件事,但无法使其正常工作。也许有人知道这是否可能以及如何实现?

enum Status {
  TIME = 'time',
  LOCATION = 'location'
}

function getStatus(statusToGet: Status[]) {
  // This function will always return an object containing all passed in
  // status as a key and boolean as a value, e.g.
  return statusToGet.reduce((prev, stat) => {
    prev[stat] = true; // or false
    return prev;
  }, {});
}

getStatus([]) // -> {}
getStatus([Status.TIME]) // -> { time: true }
getStatus([Status.TIME, Status.LOCATION]) // -> { time: true, location: false }

是否可以正确键入getStatus函数,以便TS知道返回类型中有哪些键?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以使用映射类型将字符串字面量类型的数组映射到对象:

    enum Status {
        TIME = 'time',
        LOCATION = 'location'
    }
    
    function getStatus<T extends Status>(statusToGet: T[]): { [P in T]: boolean } {
        return null as any;
    }
    
    getStatus([]) // -> {}
    getStatus([Status.TIME]) // -> { time: true }
    getStatus([Status.TIME, Status.LOCATION]) // -> { time: true, location: false }
    

    注意 如果未启用严格的空值检查,上述代码会为空数组返回{ [s:string] :any}。发生这种情况是因为T 将被推断为any。为了解决这个问题,我们可以使用条件类型来测试T 是否为any 并显式返回{}(对于来自此answer 的任何测试,10x 到@jcalz)。这确实意味着any 的任何数组都会产生{},但是由于我们期望枚举值数组而不是任何数组,这可能不是太大的问题,实际上可能是一个特性。

    function getStatus<T extends Status>(statusToGet: T[]): true extends false & T?  {} : { [P in T]: boolean } {
         return null as any;
    }
    

    【讨论】:

    • 完美,这似乎完全有效!谢谢。我总是试图将整个数组放在泛型类型中:'D 一旦阻塞​​时间结束,就会标记为正确。
    • 这也是我的方法,但第一个示例(带有空数组)的返回类型为{[x: string]: boolean},它允许任何键。是否有可能让它以某种方式返回空对象{} 而没有索引签名?
    • 上面的方法我都试过了,传入一个空数组的时候,给我返回一个空对象?
    • @CRice 添加了一个可以关闭 stric null 检查的版本
    猜你喜欢
    • 2018-09-19
    • 1970-01-01
    • 2019-01-07
    • 2020-04-27
    • 2017-03-09
    • 1970-01-01
    • 2020-10-20
    • 2022-12-21
    • 2021-07-18
    相关资源
    最近更新 更多