sorry im very new to typescript and can't figure out what's wrong in my case. Also it would be nice to hear some suggesting for more effective ways to solve my problem too.
I have some objects (for example "button" and "text"), that combined into one union type: 'element'
For now, when I get input data it typed as 'element' and in order to parse it I should now what actual element I have: text or button.
I prepare a working example, I try to use condition types and check unique "type" field in object to set final correct type - but it fails:
https://codesandbox.io/s/gifted-http-5edxyq?file=/src/App.tsx
Property 'width' does not exist on type 'element'.
Property 'width' does not exist on type 'text'.ts(2339)
My current (working) implementation is:
let currentEl: any = null;
switch (element.type) {
case 'button':
currentEl = element as button;
break;
case 'text':
currentEl = element as text;
break;
default:
console.log('No elements type matches');
break;
}
Yes it works but i need to copypast this code everywhere when unknown element typing needed.
CodePudding user response:
You need to define user-defined type guards in order to validate your input against certain type(s). Those guards are most useful when element can be isomorphic(to have more than one type) or when element can have on of many union types, which is your case. More about guards can be found here enter link description here
For example, you can define guards like this:
const isButton= (el: element): el is button=> el.type === "button";
const isText= (el: element): el is text => el.type === "text";
And then use it inside your function like this:
function elementGetter(el: element) {
const elementIsButton = isButton(el);
const elementIsText = isText(el);
if(elementIsButton) {
// Do smth..
}
if(elementIsText) {
// Do smt else
}
}
Great thing about type guards is the fact that they do work together with compiler, meaning, for example, that inside if(elementIsButton)
guard will let compiler to know that element
is of type button
.