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

Posted

技术标签:

【中文标题】打字稿:如果 multiSelect 为真,那么我想更改类型【英文标题】:Typescript: If multiSelect is true, then I want to change the types 【发布时间】:2021-06-14 14:19:27 【问题描述】:

目前我在打字稿方面遇到了一些麻烦。 当multiSelect 为真时,我有一个 React 组件,其中一些打字稿定义应该更改。当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[]'.。如您所见,它与 & 连接,但在接口定义中您可以看到我使用带有 | 的条件类型。 你有什么想法吗?

感谢您的帮助!

【问题讨论】:

只需使用as。喜欢onUpdate(selectedUserIds as string[]) 【参考方案1】:

问题出在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 问题中但无法找到链接

更新

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

【讨论】:

@JanHöck 这很奇怪,因为它在 TS 操场上工作。你有哪个版本的 TS? 尝试在你的IDE中关闭并打开这个文件,可能是缓存 if(props.multiSelect === false),你可能没有strictNullChecks @JanHöck 关于操场,有时会发生。只需从答案中复制/粘贴我的代码 @RobertoZvjerković 谢谢,问题出在strictNullChecks

以上是关于打字稿:如果 multiSelect 为真,那么我想更改类型的主要内容,如果未能解决你的问题,请参考以下文章

React 条件渲染组件打字稿

扩展排他联合的打字稿通用参数

打字稿:“关注”条件类型

如果参数为空,则打字稿函数返回类型为空

打字稿允许 arguments.callee.name?

Visual Studio Code 中的打字稿是不是有自动导入功能?