You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Generic type 'ControlProps' requires 2 type argument(s). TS2314 #4308
I can't figure out what in the react-select changelog caused this but upgrading to react-select@3.1.1 has broken my Chromatic deployments so I'm assuming the type of something changed.
Here's the error: Generic type 'ControlProps' requires 2 type argument(s). TS2314
This error is actually originating from a lot of types I've used from @types/react-select including NoticeProps, OptionProps, ValueType, etc. I'm assuming it's because of the upgrade because with react-select@3.1.0, everything worked smoothly.
Feel free to look at the logs of the errors for more details or the source.
These errors originate from a recent change in @types/react-select. Most of these types now take a second generic parameter (IsMulti) that specifies whether isMulti is set to true. In most cases, you should be safe setting that to boolean if you want to allow isMulti to be either true or false.
Let me know if you have any more questions about how to deal with the new IsMulti generic parameter. Also, if you have an issue with the TypeScript types in the future, the DefinitelyTyped repo is probably a better place to create the issue. Just make sure to tag me and I'll get around to taking a look at it.
Running into the same issue as well but with ValueType, been using this package for over a year on a client's project and it broke all of our pipelines. In the future you guys should make type changes like that a major version upgrade not a minor so it doesn't break builds.
Reacted by Abhijeet Singh, Ilya Markov, trace, Ahnaf and Antero Fagerstedt
@prescottbreeden This is due to a change in @types/react-select hosted on DefinitelyTyped (not this repository). @types package versions do not follow SemVer so you should pin your package versions to an exact package version to avoid these sorts of problems in the future. Unfortunately breaking changes in minor/patch versions of @types packages are inherent to @types and there's no way around this problem (that I know of).
If you have any issues with the new types, let us know. We're only looking to improve the types, so feedback would be appreciated if that's not the case.
Okay, so we put boolean as a second argument. And what do we do with the error in isMulti?
<MySelectisMulti/>
now gives the following error: Type 'true' is not assignable to type 'false | undefined'.ts(2322) Select.d.ts(141, 3): The expected type comes from property 'isMulti' which is declared here on type 'IntrinsicAttributes & SearchProps'
If you have a custom Select component (in this case MySelect), you'll likely have to add IsMulti as a second generic parameter (i.e., IsMulti extends boolean) to the type of MySelect and pass IsMulti along to the Select component within MySelect.
If you need more specific help than that, you'd have to show me the code for MySelect.
(you'll have to import OptionTypeBase from react-select).
Although I will warn you that your types aren't actually safe, since you're not propagating the generics. So there are potential bugs that the types should be catching for you, but won't be able to because you're essentially throwing away the generics.
@prescottbreeden Just so you know, you shouldn't have to roll react-select itself back. Just pinning @types/react-select to @types/react-select@3.0.26 should be sufficient.
What does this mean? It means that if we're dealing with a single-select component (IsMulti is false) then we know that ValueType will not be an array. But if we know that we're dealing with a multi-select component (IsMulti is true) then we know that ValueType will be an array.
A practical example (see this CodeSandbox for the full code) where this makes a difference is the callback function passed into the onChange prop which provides an argument of type ValueType<OptionType> as it's first parameter. Previously code like this would result in a type error:
export default class App extends React.Component {
onChange = (newValue: ValueType<OptionType>) => {
if (newValue != null) {
// TS error: "Property 'label' does not exist on type 'OptionType | OptionType[]'."
// To fix this we would have to cast `newValue` to `OptionType`.
console.log(newValue.label);
}
};
render() {
return <Select options={colourOptions} onChange={this.onChange} />;
}
}
However we know that it's not an array because this isn't a multi-select component and we shouldn't have to cast. Therefore we can now set the second generic parameter to false to specify that this is not a multi-select component and now it compiles correctly:
It is part of the Props type, it's just that it defaults to false (and is therefore optional). If you don't provide it, and you don't set the isMulti prop to true, it will set it to false and assume you're dealing with a single-select component.
Reacted by Abhijeet Singh, D A, Marks Paskannijs and Yarden
And yeah, I know the types could use some improvements. But that's mostly just because I'm not familiar with generics and just wanted to make react-select "work" in TypeScript with some sort of type checking.
It would be really great if there was some sort of implementation guide or reference available for how to properly use react-select with TypeScript. But unfortunately, the best I could find was scattered information across GitHub issues and StackOverflow answers.
I kinda started this repository to serve as an implementation reference for react-select with TypeScript and that eventually became this component.
@cseas Looks like you the use case I provided above is actually pretty common in your code base. I made a PR to fix the types in your project so that you don't have to cast in onChange anymore.
These errors originate from a recent change in @types/react-select. Most of these types now take a second generic parameter (IsMulti) that specifies whether isMulti is set to true. In most cases, you should be safe setting that to boolean if you want to allow isMulti to be either true or false.
Let me know if you have any more questions about how to deal with the new IsMulti generic parameter. Also, if you have an issue with the TypeScript types in the future, the DefinitelyTyped repo is probably a better place to create the issue. Just make sure to tag me and I'll get around to taking a look at it.
How about making the isMulti attribute optional? You would not break the codebases and usually people wants selects to have just single option but mainly for the first reason.
Yeah, there are more places where it could be optional, feel free to make a PR on DefinitelyTyped. We recently merged a TypeScript conversion PR in the main code base though (#4489) which we plan to release as react-select@5. In these types I've made most of the external-facing types have optional IsMulti generics.
Activity
Methuselah96 commentedon Dec 2, 2020
These errors originate from a recent change in
@types/react-select. Most of these types now take a second generic parameter (IsMulti) that specifies whetherisMultiis set totrue. In most cases, you should be safe setting that tobooleanif you want to allowisMultito be eithertrueorfalse.Let me know if you have any more questions about how to deal with the new
IsMultigeneric parameter. Also, if you have an issue with the TypeScript types in the future, the DefinitelyTyped repo is probably a better place to create the issue. Just make sure to tag me and I'll get around to taking a look at it.prescottbreeden commentedon Dec 2, 2020
Running into the same issue as well but with ValueType, been using this package for over a year on a client's project and it broke all of our pipelines. In the future you guys should make type changes like that a major version upgrade not a minor so it doesn't break builds.
Methuselah96 commentedon Dec 2, 2020
@prescottbreeden This is due to a change in
@types/react-selecthosted on DefinitelyTyped (not this repository).@typespackage versions do not follow SemVer so you should pin your package versions to an exact package version to avoid these sorts of problems in the future. Unfortunately breaking changes in minor/patch versions of@typespackages are inherent to@typesand there's no way around this problem (that I know of).If you have any issues with the new types, let us know. We're only looking to improve the types, so feedback would be appreciated if that's not the case.
prescottbreeden commentedon Dec 2, 2020
I see, that makes sense, thanks for the extra info
cseas commentedon Dec 2, 2020
Okay, so we put boolean as a second argument. And what do we do with the error in
isMulti?now gives the following error:
Type 'true' is not assignable to type 'false | undefined'.ts(2322) Select.d.ts(141, 3): The expected type comes from property 'isMulti' which is declared here on type 'IntrinsicAttributes & SearchProps'Methuselah96 commentedon Dec 2, 2020
If you have a custom
Selectcomponent (in this caseMySelect), you'll likely have to addIsMultias a second generic parameter (i.e.,IsMulti extends boolean) to the type ofMySelectand passIsMultialong to theSelectcomponent withinMySelect.If you need more specific help than that, you'd have to show me the code for
MySelect.cseas commentedon Dec 2, 2020
Yeah, the source is here.
The type of custom
Selectcomponent extends{ Props }from"react-select"I'm a bit confused. What is
IsMultiand why is it not a part ofPropsfrom react-select? Sorry, I'm not really good with generics.prescottbreeden commentedon Dec 2, 2020
I took the low road and rolled back my types and react-select to 3.0.8
Methuselah96 commentedon Dec 2, 2020
@cseas The easiest way to fix your case is to change
to
(you'll have to import
OptionTypeBasefromreact-select).Although I will warn you that your types aren't actually safe, since you're not propagating the generics. So there are potential bugs that the types should be catching for you, but won't be able to because you're essentially throwing away the generics.
Methuselah96 commentedon Dec 2, 2020
@prescottbreeden Just so you know, you shouldn't have to roll
react-selectitself back. Just pinning@types/react-selectto@types/react-select@3.0.26should be sufficient.Methuselah96 commentedon Dec 2, 2020
@cseas
The
IsMultigeneric makes it so that we can correctly narrowValueTypein various scenarios. PreviouslyValueTypelooked like this:Now it looks like this:
What does this mean? It means that if we're dealing with a single-select component (
IsMultiisfalse) then we know thatValueTypewill not be an array. But if we know that we're dealing with a multi-select component (IsMultiistrue) then we know thatValueTypewill be an array.A practical example (see this CodeSandbox for the full code) where this makes a difference is the callback function passed into the
onChangeprop which provides an argument of typeValueType<OptionType>as it's first parameter. Previously code like this would result in a type error:However we know that it's not an array because this isn't a multi-select component and we shouldn't have to cast. Therefore we can now set the second generic parameter to
falseto specify that this is not a multi-select component and now it compiles correctly:It is part of the
Propstype, it's just that it defaults tofalse(and is therefore optional). If you don't provide it, and you don't set theisMultiprop totrue, it will set it tofalseand assume you're dealing with a single-select component.cseas commentedon Dec 2, 2020
Thanks a lot for the help and explanation!
I was able to make it work.
For anyone looking for reference, here's how I fixed the breaking types.
And yeah, I know the types could use some improvements. But that's mostly just because I'm not familiar with generics and just wanted to make
react-select"work" in TypeScript with some sort of type checking.It would be really great if there was some sort of implementation guide or reference available for how to properly use react-select with TypeScript. But unfortunately, the best I could find was scattered information across GitHub issues and StackOverflow answers.
I kinda started this repository to serve as an implementation reference for react-select with TypeScript and that eventually became this component.
Methuselah96 commentedon Dec 2, 2020
@cseas Looks like you the use case I provided above is actually pretty common in your code base. I made a PR to fix the types in your project so that you don't have to cast in
onChangeanymore.SebVory commentedon May 6, 2021
How about making the
isMultiattribute optional? You would not break the codebases and usually people wants selects to have just single option but mainly for the first reason.Methuselah96 commentedon May 7, 2021
Yeah, there are more places where it could be optional, feel free to make a PR on DefinitelyTyped. We recently merged a TypeScript conversion PR in the main code base though (#4489) which we plan to release as
react-select@5. In these types I've made most of the external-facing types have optionalIsMultigenerics.