我可以使用TypeScript根据对象的键来强制其值吗?

时间:2018-06-28 05:16:27

标签: typescript

我有以下几种类型:

type Filter = {
  display: string
  id: string
  argType: 'string' | 'number' | 'date' | 'none'
}

type FilterMap = {[key: string]: Filter}

但是,在此应用程序中,string中的每个FilterMap键都必须与相应id值的Filter属性匹配。

到目前为止,我已经设法使它起作用:

type Filter<ID extends string> = {
  display: string
  id: ID
  argType: 'string' | 'number' | 'date' | 'none'
}

type FilterMap<IDS extends string> = {[ID in IDS]: Filter<ID>}

let x: FilterMap<'foo' | 'bar'> = {
  foo: {display: 'Foo', id: 'foo', argType: 'string'},
  bar: {display: 'Bar', id: 'bar', argType: 'string'},
}

例如,如果倒数第二行改为读取bar: {display: 'Bar', id: 'baz', argType: 'string'},,这将产生错误!

是否有一种方法可以做到而不必第三次键入所有键,因为我必须在此处输入FilterMap的type参数? / p>

1 个答案:

答案 0 :(得分:1)

如果利用函数的推断行为,则可以执行此操作。我们可以创建一个具有泛型参数的函数来表示字符串文字类型的并集,然后让编译器确定该类型是什么,它将做什么。

type Filter<ID extends string> = {
    display: string
    id: ID
    argType: 'string' | 'number' | 'date' | 'none'
}

type FilterMap<IDS extends string> = { [ID in IDS]: Filter<ID> }


function createFilterMap<T extends string>(fm: FilterMap<T>) {
    return fm
}

// Will be of type FilterMap<"foo" | "bar">
let x = createFilterMap({ 
    foo: { display: 'Foo', id: 'foo', argType: 'string' },
    bar: { display: 'Bar', id: 'bar', argType: 'string' },
})