currently I have some troubles with typescript.
I have a React component, where some typescript definitions should change, when multiSelect
is true. onUpdate
and value
will be forced to a string OR string[] when multiSelect
is true or false. But is doesn't work.
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;
The React component looks like this
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 ...;
};
In handleSelectUser
I get the error TS2345: Argument of type 'string' is not assignable to parameter of type 'string & string[]'. Type 'string' is not assignable to type 'string[]'.
. As you can see, it is connected with a & but in the interface definition you can see that I use conditional types with |.
Do you have any ideas ?
Thank for your help!
The problem is in destructuring
. TS has problems with it :)
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
}
Just use props.onUpdate
instead of onUpdate
.
I believe such behaviour is logged in gtihub issues but unable to find a link
UPDATE
If it still don't work, please enable strictNullChecks
Thanks @Roberto Zvjerković for the tip!