I need to develop a function that accept 2 type of input.
type InputA = {
name: string
content: string
color: string
}
type InputB = {
name: string
content: number
}
type Input = InputA | InputB
When I try to implement the function accepting this 2 inputs, I would like to check if the input has the color
attribute, so I can distinct the 2 types.
However this will lead me to a compiler error:
function foo(input:Input){
const color = (input.color) ? input.color : undefined;
// ^
// | Property 'color' does not exist on type 'Input'.
// | Property 'color' does not exist on type 'InputB'.
...
}
I know I can implement a new attribute, like type_name
, that exists in both types and then check on that one. But I would like to avoid it since I don't like having an extra attribute only for this reason in this particular function.
Is there a better way?
CodePudding user response:
For type-safety reasons, you can't access properties which might not exist on a union type with the dot-notation. Use the in
operator instead.
function foo(input:Input){
const color = "color" in input ? input.color : undefined
}
CodePudding user response:
U can propose another approach to use type predicates since you can use them for a lot more than the color property once you define the type identification logic.
// tells the typescript whether the variable is of type InputA
const isOfTypeInputA = (input: Input): input is InputA => {
return input.hasOwnProperty("color");
}
function foo(input:Input){
const color = isOfTypeInputA(input) ? input.color : undefined;
}
Working solution here: Typescritp playground link