using typescript's jsdoc support to type the following javascript code:
const [optionalNumber, setOptionalNumber] = useState(null)
const handleClick = () => {
setOptionalNumber(42)
// ^-- Argument of type '42' is not assignable to parameter of type 'SetStateAction<null>'
}
the way i currently get around this works but is a bit ugly:
const [optional, setOptional] = useState(
/** @type {number|null} */ (null)
)
how can i acplish this without using casting? i want optional
to have a type of null | number
, and setOptional
to only accept null | number
as an argument.
codesandbox demonstrating this:
using typescript's jsdoc support to type the following javascript code:
const [optionalNumber, setOptionalNumber] = useState(null)
const handleClick = () => {
setOptionalNumber(42)
// ^-- Argument of type '42' is not assignable to parameter of type 'SetStateAction<null>'
}
the way i currently get around this works but is a bit ugly:
const [optional, setOptional] = useState(
/** @type {number|null} */ (null)
)
how can i acplish this without using casting? i want optional
to have a type of null | number
, and setOptional
to only accept null | number
as an argument.
codesandbox demonstrating this:
https://codesandbox.io/s/optimistic-villani-kbudi?fontsize=14
-
Just use undefined instead of null:
const [optional, setOptional] = useState()
– Jared Smith Commented Oct 9, 2019 at 21:30 -
i still want this limited to {null|number} - useState with no args results in optional being
any
– schpet Commented Oct 9, 2019 at 21:33 - updated with more context about this – schpet Commented Oct 9, 2019 at 21:35
- 1 It's not currently possible... there is an open issue for it: github./microsoft/TypeScript/issues/27387 – Kyle Commented Mar 20, 2020 at 6:03
2 Answers
Reset to default 7I think you can define an initial value with the correct union type and pass it to useState
.
It would be something like this:
/**
* @type {number | null}
*/
const initValue = 42;
const [optionalNumber, setOptionalNumber] = useState(initValue)
Assuming that your ponent relies on the inital state of the optional
state being the null
value (rather than undefined
), one solution would be to explicitly specify the state hooks type as a union type of both number
and null
like so:
// Allows initial value to be null, and number to be subsequently set
const [optional, setOptional] = useState<number | null>(null);
// optional === null
setOptional(42);
Alternatively, if your ponent does not distingush between undefined
or null
for the inital optional
state value, then the following would work:
const [optional, setOptional] = useState<number>();
// optional === undefined
setOptional(42);