4

I have a following component (simplified version):

type ValueHelper<Clearable extends boolean> = Clearable extends true
    ? string | null
    : string;

type Props<Clearable extends boolean> = {
    clearable?: Clearable;
    onChange: (value: ValueHelper<Clearable>) => void;
    value: ValueHelper<Clearable>;
};

const Input = <Clearable extends boolean = false>({ clearable, value, onChange }: Props<Clearable>) => {
    const handleChange = (event) => {
        const inputValue = event.target.value;
        if (clearable && inputValue === '') {
            onChange(null);
            return;
        }
        onChange(inputValue);
    }

    return (
        <input value={value} onChange={handleChange} />
    );
}

For some reason TypeScript complains about null argument in onChange function, which seems to be wrong, since my conditional type ValueHelper checks if clearable is true, and if so, null should be allowed.

enter image description here

Any ideas?

1 Answer 1

2

This is a limitation of Typescript; Typescript does control-flow type narrowing on variables, but not on type variables like your Clearable. So a test like if(clearable) can narrow the type of the variable clearable to be something more specific than Clearable, but it cannot narrow Clearable itself to be something more specific. Therefore as far as Typescript is concerned, it's as if you didn't do the if check and Clearable could still be string instead of string | null.

In this case a type assertion is probably the simplest solution: you know that null is assignable to ValueHelper<Clearable> in this branch even if Typescript doesn't know it, so instead of null you can write null as ValueHelper<Clearable>.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.