Whenever I utilize a union type where one of the types is any
, the TypeScript editor doesn't seem to correctly determine the type. Here is an example:
interface ITest {
name: string;
age: number;
}
interface ITest2 {
last: string;
dob: number;
}
function isGood(input: any) : input is ITest{
return 'name' in input && 'age' in input;
}
function doIt(){
var data : ITest2 | ITest = {
last: 'Test', dob: 123
}
var data2 : any | ITest = {
name: 'else', age: 45
}
if(isGood(data)){
alert(`name:${data.name}, age:${data.age}`); // data shows ITest
}
if(isGood(data2)){
alert(`name:${data2.name}, age:${data2.age}`); // data2 shows any
}
}
doIt();
The code does work properly, but the developer experience at design time isn't as expected (both in VS Code - 1.4.0 and in the TypeScript playground - 1.8).
As anticipated, the following line infers that data
is of type ITest
based on the type guard.
alert(`name:${data.name}, age:${data.age}`); // data shows ITest
However, with the second part involving data2
, it fails to infer the correct type and defaults to any
:
alert(`name:${data2.name}, age:${data2.age}`); // data2 shows any
In this scenario, it's expected for intellisense to recognize that data2
should be of type
ITest</code, similar to how it did for <code>data
.
I have attempted swapping the placement of the two types in the union declaration, however, it didn't alter the outcome.
Is there something I'm overlooking?
Practical Application
The actual situation I'm dealing with involves receiving a response from an HTTP call. Initially, it has to be of type any
since the HTTP clients are unaware of our data types.
Nevertheless, I aim to create a user-defined type guard that validates the desired properties from that json object, then extracts only the necessary data and returns it.