I think I'm missing something basic on how you can check for a truthy value with && in Typescript.
Why can props.function still be undefined in test1 and has to be checked like I did in test2.
import React from "react";
interface PropsModel {
label?: string
function?: Function,
}
function test1(props: PropsModel) {
return (
<div>
{props.label && <p>{props.label}</p>} // props.label is checked for undefined
{props.function && <button onClick={() => props.function()}>Dummy button</button>} // props.function is not checked for undefined
</div>
)
}
function test2(props: PropsModel) {
return (
<div>
{props.label && <p>{props.label}</p>} // props.label is checked for undefined
{props.function && <button onClick={() => {if (props.function) props.function()}}>Dummy button</button>} // props.function is checked for undefined
</div>
)
}
EDIT 1: Added Link to playground
Link to Typescript playground
CodePudding user response:
I am by no means an expert on this matter of TS as I too have wondered this. My assumption so far is to do with the level of "scope". Aka the onClick
function is of a different scope to your Component. If you're 100% sure that the function will exist within the OnClick you can do either of the below.
import React from "react";
export type Function = () => void;
export type Input = {
label?: string;
function?: Function;
}
function test1(props: Input) {
return (
<div>
{props.label && <p>{props.label}</p>} // props.label is checked for undefined
{props.function && <button onClick={() => (props.function as Function)()}>Dummy button</button>} // props.function is not checked for undefined
</div>
)
}
or simply
import React from "react";
interface PropsModel {
label?: string
function?: Function,
}
function test1(props: PropsModel) {
return (
<div>
{props.label && <p>{props.label}</p>} // props.label is checked for undefined
{props.function && <button onClick={() => props.function!()}>Dummy button</button>} // props.function is not checked for undefined
</div>
)
}
A !
has been added to the {props.function && <button onClick={() => props.function!()}>Dummy button</button>}
line here. !
simply tells TS that you are 100% sure that the optional type will definitely exist at this point.
CodePudding user response:
Your function
property is optional. hence to use such property we must use optional chaining.
What you need to do is
function test1(props: PropsModel) {
return (
<div>
{props.label && <p>{props.label}</p>}
{props.function && <button onClick={() => props.function?.()}>Dummy button</button>} // props.function is checked for undefined then it will be called
</div>
)
}
Note that to use optional chaining your typescript version must be typescript >= 3.7