TypeScript:读取对象中值的通用类型
TypeScript: Read generic type of value in object
我有这个界面:
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>
for "state"
。有什么方法可以访问 Converter
中的泛型?
如果您有权访问 Converter iterface/type 或使用此类型扩展它的任何东西
或者像这样创建扩展接口
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;
}
但是这个 souliton 会把你在 write 函数中的参数设置为可选(可能未定义)
好吧,也许有更好的解决方案来访问这个通用类型。 idk
我不知道这是否有帮助,因为我不确定您的 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
界面中添加一个 属性。
我有这个界面:
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>
for "state"
。有什么方法可以访问 Converter
中的泛型?
如果您有权访问 Converter iterface/type 或使用此类型扩展它的任何东西
或者像这样创建扩展接口
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;
}
但是这个 souliton 会把你在 write 函数中的参数设置为可选(可能未定义)
好吧,也许有更好的解决方案来访问这个通用类型。 idk
我不知道这是否有帮助,因为我不确定您的 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
界面中添加一个 属性。