在TypeScript中对变量键控对象的通用访问

时间:2018-04-23 14:04:51

标签: typescript

让我们假设我有以下接口(从我的项目中非常简化):

interface A {};
interface B {};

interface State {
  a: A[];
  b: B[];
}

以及以下功能:

function getData<T extends keyof State>(name: T): State[T] {
  return state[name];
}

getData('a') // returns strongly typed A[]
getData('b') // returns strongly typed B[]

这对我的多个应用程序来说非常有用,我想放入一个库。遗憾的是,它直接取决于State,所以我需要一个足够通用的新接口来描述任何类型的状态,其中键(a,b)是通用的(因此没有固定名称,没有固定类型)来替换函数签名中的State - 同时仍然从getData返回一个强类型,所以这样的东西(我知道这不起作用,它只是伪代码):

interface StateDescribing {
  [key: string]: SomeGenericMagic
}

function getData<U extends StateDescribing, T extends keyof u>(state: U, name: T): U[T] {
  return state[name];
}

关于如何编写该界面的任何想法?

2 个答案:

答案 0 :(得分:0)

如果您只想从U返回值,则不需要对U进行任何限制。这样可以正常工作:

interface A { };
interface B { };

interface State {
    a: A[];
    b: B[];
}

declare var state: State;

function getData<U, T extends keyof U>(state: U, name: T): U[T] {
    return state[name];
}

getData(state, 'a') // returns strongly typed A[]
getData(state, 'b') // returns strongly typed B[]

答案 1 :(得分:0)

您不需要任何界面:

function getData<T, K extends keyof T>(state: T, name: K): T[K] {
  return state[name];
}


const a = getData('hola', 'length'); // a: number. OK
const b = getData(23, 'toString'); // b: function. OK
const c = getData(23, 'length'); // error. No 'length' in number

此功能适用于每个对象,不仅适用于特定类型