TypeScript ジェネリクスと型ガードの組み合わせ

覚書です。

const createAction = <I extends Q, Q, O>(
    input: Q,
    guard: (x: Q) => x is I,
    converter: (_: I) => O,
    restore: (_: O) => any
) => {
    if (guard(input)) {
        const converted = converter(input);
        return restore(converted);
    }
    return undefined;
};

使い方。

const guardAge = (age: number | undefined): age is number => typeof age === 'number';
const convertAge = (age: number) => age + '';
const setAge = (age: string) => {
    return {
        type: 'SET_AGE',
        payload: age
    }
};
const createAge = (value: number, empty = false): number | undefined => empty ? undefined : value;

createAction(createAge(33), guardAge, convertAge, setAge);