Reputation: 146
I have two object types and the input of a function can be either one:
export default function Eingabefeld({
isText=true,
children="",
}:(
{
isText: true,
children:string
} | {
isText: false,
children:number
}
)) {
if (isText === true) {
let data:string = children
data;
}else if (isText === false) {
let data:number = children
data;
}
}
Why does TS gives me this error
as if i would have used the "AND" expression to merge the two object types?
Edit: It is a TypeScript bug. See: Discriminated union parameter destructuring doesn't work if the fields have defaults
Upvotes: 1
Views: 63
Reputation: 146
There are multiple ways of solving this.
export function Inputfield(props:(
{
isText: true,
children:string
} | {
isText: false,
children:number
}
)) {
if (props.isText === true) {
let data:string = props.children
}else if (props.isText === false) {
let data:number = props.children
}
}
export function Inputfield(props:(
{
isText: true,
children:string
} | {
isText: false,
children:number
}
)) {
if (props.isText === true) {
let {children} = props
let data:string = children
}else if (props.isText === false) {
let {children} = props
let data:number = children
}
}
type props_type = {
isText: true,
children:string
} | {
isText: false,
children:number
}
export function Inputfield(_props:(
Partial<props_type>
)) {
const props = {
isText: true,
children: "",
..._props
} as props_type
if (props.isText === true) {
let data:string = props.children
}else if (props.isText === false) {
let data:number = props.children
}
}
this can also be written with more bloating if undefined assignments
type props_type = {
isText: true,
children:string
} | {
isText: false,
children:number
}
function Inputfield(_props:(
Partial<props_type>
)) {
if (_props.isText == undefined) _props.isText = true;
if (_props.children == undefined) _props.children = "";
// do NOT use `_props.isText ||= true;`, because if isText is false the default value will be applied
const props = _props as props_type;
if (props.isText === true) {
let data:string = props.children
}else if (props.isText === false) {
let data:number = props.children
}
}
export function Inputfield(props:(
{
isText: true,
children:string
} | {
isText: false,
children:number
}
)={
isText:true,
children:"",
}) {
if (props.isText === true) {
let data:string = props.children
data;
}else if (props.isText === false) {
let data:number = props.children
data;
}
}
When defaults are used as individual values, not assigning a property will use the default value. When giving a default object, only if no input object is given, the default is used.
The ways of accessing the properties and applying the default values may be mixed together as needed.
Upvotes: 1