如何基于类型化对象数组中的值限制类型?

时间:2019-01-19 08:13:09

标签: typescript

假设我有一个对象数组,并且我想将函数的参数限制为那些对象的键值...我可以使用Typescript来做到这一点吗?我宁愿避免创建所有值的枚举...

const fonts = [
  {
    value: 'Font Name 1',
    label: 'Font Label 1',
  },
  {
    value: 'Font Name 2',
    label: 'Font Label 2',
  },
];

function doSomething(value) {
  // Do something.
}

function doSomethingElse(label) {
  // Do something.
}

doSomething('Font Name 1'); // good
doSomething('Font Name 2'); // good
doSomething('Font Name 3'); // error

doSomething('Font Label 1'); // good
doSomething('Font Label 2'); // good
doSomething('Font Label 3'); // error

这可能吗?

1 个答案:

答案 0 :(得分:0)

可以,但是在分配fonts时需要使用一个函数,以帮助打字稿推断值和标签的字符串文字类型。

然后我们可以使用类型查询来获取valuelabel的类型,它们将是字符串文字类型的并集

function createFonts<T extends Array<{ value: V, label: L }>, V extends string, L extends string>(...o: T) {
    return o
} 
// Type as  [{ value: "Font Name 1"; label: "Font Label 1"; }, { value: "Font Name 2"; label: "Font Label 2"; }]
const fonts = createFonts({
    value: 'Font Name 1',
    label: 'Font Label 1',
},
{
    value: 'Font Name 2',
    label: 'Font Label 2',
})

function doSomething(value: typeof fonts[number]['value']) {
// Do something.
}

function doSomethingElse(label: typeof fonts[number]['label']) {
// Do something.
}

doSomething('Font Name 1'); // good
doSomething('Font Name 2'); // good
doSomething('Font Name 3'); // error

doSomethingElse('Font Label 1'); // good
doSomethingElse('Font Label 2'); // good
doSomethingElse('Font Label 3'); // error