Home > Software design >  Not detecting correct types
Not detecting correct types

Time:12-07

In the following code, why is the callback assuming string | number | boolean as the type instead of detecting the exact type based on the property that is being passed as the first argument of carWithListener.on function?

const car = {
    paint: "red",
    tires: "mrf",
    brakes: "disk",
    bluetooth: true,
    mileage: 7.45
}

type PropChangeListener<T> = {
    on<Key extends string & keyof T>(
        prop: `on${Capitalize<Key>}Changed`, 
        callback: (val: T[Key]) => T[Key]
    ): void
}

declare function registerForChanges<T>(obj: T): PropChangeListener<T>
const carWithListener = registerForChanges(car);
carWithListener.on("onBluetoothChanged", (val: boolean) => !val)

CodePudding user response:

You need to specify which key the listener is on

const car = {
    paint: "red",
    tires: "mrf",
    brakes: "disk",
    bluetooth: true,
    mileage: 7.45
}

type PropChangeListener<T> = {
    on<Key extends string & keyof T>(
        prop: `on${Capitalize<Key>}Changed`, 
        callback: (val: T[Key]) => T[Key]
    ): void
}

declare function registerForChanges<T>(obj: T): PropChangeListener<T>
const carWithListener = registerForChanges(car);
carWithListener.on<'bluetooth'>("onBluetoothChanged", (val: boolean) => !val)

TS Playground: https://tsplay.dev/mAv1vW

The statement

callback: (val: T[Key]) => T[Key]

says, the callback is a function that can take any of the type of the attributes of T. So, it can take string | number | boolean unless you specify which key the listener is about.

  • Related