TypeScript:读取对象中值的通用类型

时间:2019-06-19 08:49:51

标签: typescript generics typescript-typings typescript-generics

我有这个界面:

interface Api {
  state: Converter<State>;
  water: Converter<Water>;
  version: Converter<Versions>;
}

我有一个名为write

的函数
write(name, value);

现在我要实现的是value的类型应该是Converter的泛型,具体取决于第一个参数(name)。

因此,如果我打电话给write("state", value)-> value应该是State"water""version"也是如此。

write("state, value);    // value should be type of State
write("water", value);   // value should be type of Water
write("version", value); // value should be type of Versions

我实现了第一个参数,如下所示:

write(name: keyof Api, value: ???)

我发现可以像这样获得keyof Api的相应值:

write<K extends keyof Api>(name: K, value: Api[K])

但是我得到Converter<State>的{​​{1}}。有什么方法可以访问"state"中的泛型?

2 个答案:

答案 0 :(得分:3)

如果您有权使用Converter的iterface /类型或仅使用此类型进行扩展的

或创建这样的扩展接口

interface Converter<T> {
  p1: any;
  p2: any;
}
interface IExtendedConverter<T> extends Converter<T> {
  type: T;
}

interface IApi {
  state: IExtendedConverter<string>;
  water: IExtendedConverter<number>;
}

const write = <K extends keyof IApi>(name: K, value: IApi[K]['type']) => {
  return;
};

const str = write('state', '1'); // here value has to be string
const num = write('water', 1); // here value has to be number

根据问题进行编辑

可以定义一个解决方案

const extendedConverterState: IExtendedConverter<string> = {
  ...converter,
  type: '',
};

const extendedConverterNumber: IExtendedConverter<number> = {
  ...converter,
  type: 1,
};

const api: IApi = {
  state: extendedConverterState,
  water: extendedConverterNumber,
};

这是一种受阻的解决方案,因为您只会创建此属性,因此永远不会使用。

另一种解决方案是将类型参数创建为optionla

interface IExtendedConverter<T> extends Converter<T> {
  type?: T;
}

但是此解决方案会将您在write函数中的参数作为可选参数(可能是未定义的)

也许这是访问此通用类型的更好的解决方案。 idk

答案 1 :(得分:0)

我不确定这是否有帮助,因为不确定您的Converter界面是什么样。

但是,这个:

interface Converter<T> {
  converter: T;
}

这些StateWaterVersion的接口:

interface State {
  state: string;
}

interface Water {
  water: string;
}

interface Version {
  version: string;
}

您可以这样做:

function write<K extends keyof Api>(name: K, value: Api[K]["converter"]) {}
write("state", { state: "x" }); // Works

write("water", { state: "x" }); // Argument of type '{ state: string; }' is not assignable to parameter of type 'Water'.

write("water", { water: "x" }); // Works

但是它将属性添加到您的Converter界面中。