打字稿:如果 multiSelect 为真,那么我想更改类型

Typescript: If multiSelect is true, then I want to change the types

目前我在打字稿方面遇到了一些麻烦。 我有一个 React 组件,当 multiSelect 为真时,一些打字稿定义应该更改。当 multiSelect 为真或假时,onUpdatevalue 将被强制为字符串 OR string[]。但是是行不通的。

export interface DefaultUserTypeFieldProps {
    className?: string;
    disabled?: boolean;
    /**
     * The label of the input
     */
    label?: string;
    autoSelectUserId?: string;
}

export interface SingleUserTypeFieldProps extends DefaultUserTypeFieldProps {
    multiSelect: false;
    value: string;
    onUpdate: (value: string, isValid: boolean) => void;
}

export interface MultipleUserTypeFieldProp extends DefaultUserTypeFieldProps {
    multiSelect: true;
    value: string[];
    onUpdate: (value: string[], isValid: boolean) => void;
}

export type UserTypeFieldProps = SingleUserTypeFieldProps | MultipleUserTypeFieldProp;

React 组件如下所示

export const UserTypeField = (props: UserTypeFieldProps) => {
const {
    className,
    label,
    disabled,
    value,
    autoSelectUserId,
    multiSelect = false,
    onUpdate,
} = props;

const handleSelectUser = (selectedUserIds: string[]) => {
    close();
    if (multiSelect) {
        onUpdate(selectedUserIds, true);
    } else {
        onUpdate(selectedUserIds[0], true);
    }
};

return ...;

};

handleSelectUser 中我收到错误 TS2345: Argument of type 'string' is not assignable to parameter of type 'string & string[]'. Type 'string' is not assignable to type 'string[]'.。如您所见,它与 & 连接,但在接口定义中您可以看到我将条件类型与 | 一起使用。 你有什么想法吗?

感谢您的帮助!

问题出在destructuring。 TS 有问题:)

export interface DefaultUserTypeFieldProps {
    className?: string;
    disabled?: boolean;
    /**
     * The label of the input
     */
    label?: string;
    autoSelectUserId?: string;
}

export interface SingleUserTypeFieldProps extends DefaultUserTypeFieldProps {
    multiSelect: false;
    value: string;
    onUpdate: (value: string, isValid: boolean) => void;
}

export interface MultipleUserTypeFieldProp extends DefaultUserTypeFieldProps {
    multiSelect: true;
    value: string[];
    onUpdate: (value: string[], isValid: boolean) => void;
}

export type UserTypeFieldProps = SingleUserTypeFieldProps | MultipleUserTypeFieldProp;



export const UserTypeField = (props: UserTypeFieldProps) => {
// problem is here
    const {
        className,
        label,
        disabled,
        value,
        autoSelectUserId,
        multiSelect = false,
        onUpdate,
    } = props;

    const handleSelectUser = (selectedUserIds: string[]) => {
        close();
        if (props.multiSelect) {
// here is the fix
            props.onUpdate(selectedUserIds, true);
        } else {
            props.onUpdate(selectedUserIds[0], true);
        }
    };

    return null
}

Playground

只需使用 props.onUpdate 而不是 onUpdate

我相信这种行为已记录在 gtihub 问题中,但无法找到 link

更新

如果还是不行,请启用strictNullChecks 感谢@Roberto Zvjerković 的提示!