I have these 2 interfaces:
export interface Converter<T> {
decode?: Decoder<T>;
encode?: Encoder<T>;
notify?: Notifier<T>;
type?: T;
}
export interface Api {
state: Converter<State>;
water: Converter<Water>;
version: Converter<Versions>;
}
In this class I make use of these interfaces. Particularly, I have a function called write
where I make sure the the parameter name
is a key of the Api
interface and the value
is the corresponding Generic
of that key.
export default class Characteristic {
private api: Api;
public async write<Name extends keyof Api, Value = Api[Name]["type"]>(
name: Name,
value: Value
): Promise<void> {
const { encode } = this.api[name];
const buffer = encode(value);
// ^^^^^
}
}
This pattern works as expected, but here I get an error on value
that I don't quite understand:
Type '"sleep" | "goingToSleep" | "idle" | "busy" | "espresso" | "steam" | "hotWater" | "shortCal" | "selfTest" | "longCal" | "descale" | "fatalError" | "init" | "noRequest" | "skipToNext" | ... 7 more ... | Versions' is not assignable to type 'Value'. '"sleep" | "goingToSleep" | "idle" | "busy" | "espresso" | "steam" | "hotWater" | "shortCal" | "selfTest" | "longCal" | "descale" | "fatalError" | "init" | "noRequest" | "skipToNext" | ... 7 more ... | Versions' is assignable to the constraint of type 'Value', but 'Value' could be instantiated with a different subtype of constraint '{}'. Type '"sleep"' is not assignable to type 'Value'. '"sleep"' is assignable to the constraint of type 'Value', but 'Value' could be instantiated with a different subtype of constraint '{}'
I think Typescript is complaining about the lack of constraints on Value
here. You give it a default value, but it could be still overridden to a different type.
Do you need to make the Value
type generic there? You could change the method signature like this:
public async write<Name extends keyof Api>(
name: Name,
value: Api[Name]["type"]
): Promise<void> {
Optionally add a type helper to make it look neater:
type ValueFor<Name extends keyof Api> = Api[Name]["type"];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.