我有这个界面:
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"
中的泛型?
答案 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;
}
这些State
,Water
和Version
的接口:
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
界面中。