typescript - Är det möjligt att arbeta med elements i en array med olika unionstyper utan felet "kan inte tilldelas till parameter av typen 'never'?"


type GenericElement<T> = {
  set: Setter<T>;
  state: T;
} 

type Setter<T> = (state: T) => void

type GenericElements = Array< GenericElement<string> |  GenericElement<number>>

const genericElements = [{
  set: (state: string) => console.log(state),
  state: 'stateValue'
}, {
  set: (state: number) => console.log(state),
  state: 123
}]

genericElements.map(({set, state}) => set(state))
// ---------------------------------------|

/**
 * Argument of type 'string | number' is not assignable to parameter of type 'never'.
 * Type 'string' is not assignable to type 'never'.(2345)
*/

Exempel på TS-lekplats

Är det möjligt att implementera det utan detta problem, eller hur kan man leda den föreslagna strukturen så att den kan hantera set(state) på ett vanligt sätt utan mallar som att utföra denna operation för varje barn manuellt eller överkodningar som [() => set1(state1),() => setN(stateN)]?

Svar #1

Efter ständig undersökning har jag hittat sättet som kan fungera för mig.

Länk till TS-lekplatsen för att leka.

enum genericTypes {
    stringTypes = 'stringTypes',
    numberTypes = 'numberTypes',
}
const {numberTypes, stringTypes} = genericTypes;

type GenericElement<T extends genericTypes> = {
    set: Setter<T>;
    state: State<T>;
};

type State<T extends genericTypes> = T extends genericTypes.numberTypes ? number : string;

type States = {
    [numberTypes]: State<genericTypes.numberTypes>;
    [stringTypes]: State<genericTypes.stringTypes>;
};

type Setter<T extends genericTypes> = (state: State<T>) => void;

type Setters = {
    [numberTypes]: Setter<genericTypes.numberTypes>;
    [stringTypes]: Setter<genericTypes.stringTypes>;
};

const setters: Setters = {
    [numberTypes]: (state: State<genericTypes.numberTypes>) => console.log(state),
    [stringTypes]: (state: State<genericTypes.stringTypes>) => console.log(state),
};

const states: States = {
    [numberTypes]: 123,
    [stringTypes]: '123',
};

type GenericElements = Array<GenericElement<genericTypes>>;

const genericElements: GenericElements = [
    { set: setters.numberTypes, state: states.numberTypes },
    { set: setters.stringTypes, state: states.stringTypes },
];

genericElements.map(({ set, state }) => set(state));

Jag kommer att fortsätta undersöka för att slutligen förstå. Om någon kunde granska förslaget med feedback skulle jag vara mycket tacksam.