Машинопись: Discriminated Union со значением в параметре функции преобразуется в 'любой' - PullRequest
1 голос
/ 04 августа 2020

В обоих этих примерах не отображается тип параметра в onSelect ... TS утверждает, что value равно any, если clearable не указан.

Я нахожусь в потеря. Я пробовал как с генератором c, так и без него: без кубиков. Любая помощь?

import React from 'react';

interface RequiredProps {
    value: string;
    clearable?: false;
    onSelect: (value: string) => void;
}

interface ClearableProps {
    value: string | null;
    clearable?: true;
    onSelect: (value: string | null) => void;
}

const Select: React.FC<ClearableProps | RequiredProps> = ({ value, clearable, onSelect }) => {
    return <div />;
}

const Clearable = <Select value="abc" onSelect={(value) => { }} clearable={true} />;
const ExplicitNotClearable = <Select value="abc" onSelect={(value) => { }} clearable={false} />;

// Why doesn't TS know `value` is a `string`, but rather thinks this function has no type?
const NotClearable = <Select value="abc" onSelect={(value) => { }} />;
import React from 'react';

interface Props<T> {
    clearable?: boolean;
    onSelect: (value: T) => void;
    value: T;
}

interface RequiredProps extends Props<string> {
    clearable?: false;
}

type ClearableType = string | null;
interface ClearableProps extends Props<ClearableType> {
    clearable: true;
}

const Select: React.FC<ClearableProps | RequiredProps> = ({ value, clearable, onSelect }) => {
    return <div />;
}

const Clearable = <Select value="abc" onSelect={(value) => { }} clearable={true} />;
const ExplicitNotClearable = <Select value="abc" onSelect={(value) => { }} clearable={false} />;

// Why doesn't TS know `value` is a `string`, but rather thinks this function has no type?
const NotClearable = <Select value="abc" onSelect={(value) => { }} />;

1 Ответ

0 голосов
/ 04 августа 2020

Я немного запутался, потому что в ваших двух случаях clearable является необязательным или обязательным в ClearableProps. Я полагаю, вы имеете в виду, что это требуется в обеих версиях, верно? В любом случае, я предполагаю, что.

Это похоже на известную ошибку, microsoft / TypeScript # 31618 . Параметр обратного вызова value не набирается контекстуально , когда обратный вызов назначен свойству onSelect с типом объединения. Когда вы явно различаете объединение, задавая clearable, проблема исчезает.

Эта проблема находится в очереди, поэтому вряд ли она будет решена в ближайшее время.

Вы можете обойти это по явной аннотации типа value:

const ImplicitlyNotClearable = <Select value="abc" onSelect={(value: string) => { }} />;

, что не самое лучшее, но по крайней мере это что-то.

Хорошо, надеюсь, это поможет; удачи!

Детская площадка ссылка на код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...