【问题标题】:How can you generate a mapped type that is a tuple type?如何生成元组类型的映射类型?
【发布时间】:2017-09-25 16:34:50
【问题描述】:

假设我有一个符合定义类型的输入:

interface Person {
    name: string;
    age: number;
}

现在,我想要一个函数来接受一个键值对数组,例如:

function acceptsPersonProperties(tuple: Array<PersonTuple>) { ... }

// this should be fine:
acceptsPersonProperties([['name', 'Bob'], ['age', 42]]);

// this should give a compile-time error:
acceptsPersonProperties([['name', 2], ['age', 'Bob']]);

当然,我可以手动输入,例如:

type PersonTuple = ['name', string] | ['age', number];

但是如果类型(例如Person)是一个模板变量,那么元组如何表示为mapped type呢?

function acceptsPropertiesOfT<T>(tuple: Array<MappedTypeHere<T>>) { ... }

为了避免 X-Y 问题,真正的用例是这样的:

let request = api.get({
    url: 'folder/1/files',
    query: [
        ['fileid', 23],
        ['fileid', 47],
        ['fileid', 69]
    ]
});

解析为"/api/folder/1/files?fileid=23&amp;fileid=47&amp;fileid=69",但我想输入,所以它不允许额外的属性(file_id)并检查类型(没有字符串作为fileid)。

【问题讨论】:

    标签: typescript types


    【解决方案1】:

    你不能用元组类型来做到这一点。元组的右侧总是会泛化为 Person 中所有可能值的并集。

    但是,如果您稍微更改 API,就可以让它工作:

    interface Person {
      name: string;
      age: number;
    }
    
    function acceptsPersonProperties(tuple: Partial<Person>[]) { }
    
    // this should be fine:
    acceptsPersonProperties([{ name: 'Bob' }, { age: 42 }]);
    
    // this should give a compile-time error:
    acceptsPersonProperties([{ name: 2 }, { age: 'Bob' }]);
    

    【讨论】:

    • 感谢您的回答!我已经更新了我的问题以包括“真实世界”的场景。很遗憾,元组不可能(还没有?):/ API 不是我的,所以为了 TypeScript 合规性而改变它似乎...... hackish。
    • 我不确定我是否理解这个问题。您是否在追求这样的事情(不需要映射类型) - gist.github.com/bcherny/d70434e5bb53bb88dda29f900d385bbf
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 2018-02-05
    • 2021-05-27
    • 2021-08-04
    • 1970-01-01
    • 2020-01-17
    相关资源
    最近更新 更多