Typescript Inference
variable declaration: const color
variable initialization: ‘red’
1 |
const color = 'red'; |
If declaration and initialization are on the same line, Typescript will figure out the type of ‘color’ for us.
But when are we going to add in these type Annotations?
If typescript can figure it out, why would we want to do it yourselves?
Try to use Type Inference.
But there are THREE scenarios where we rely on Type Annotations to help Typescript out.
Scenario 1 – ‘Any’ type
Whenever a function return the any type.
1 2 3 4 5 6 7 8 9 |
// when to use annotations? // 1) function that returns the 'any' type const json = '{"x":10, "y": 20}'; // mouse over coordinates. You'll see 'Any' // mouse over parse and you'll see that the parse function returns // 'any'. const coordinates = JSON.parse(json); |
JSON.parse() –> ‘false’ –> boolean
JSON.parse() –> ‘4’ –> number
JSON.parse() –> ‘{“value”, 5}’ –> {value:number}
Can’t predict what we get in return.
So as a shortcut, typescript uses ‘Any’ type.
We have no idea what type gets returned.
type Any – means TS has no idea what this is – can’t check for correct property references
Avoid variables with ‘any’ at all costs.
The reason why is because say we have declare speed to be string:
1 |
let speed: string = 'fast'; |
if we then go
1 |
speed.abcdef |
TS will let us know that property abcdef does not exist. Because TS knows that speed is a string.
But with Any, TS doesn’t know, and won’t be able to do this check for you.
Scenerio 2 – How to use Use Type Annotation to Fix the ‘Any’ Type
We can add type annotation for object.
Say we’re expecting an object where there’s a x and y property of type number.
1 |
const coordinates: { x: number, y: number } = JSON.parse(); |
Now if we mouse over coordinates, or try to access a weird random property, we’ll get proper feedback or error.
Delayed Initialization
Another way to add type annotation manually…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// 2) When we declare a variable on oneline // and initialize it later let words = ['red', 'green', 'blue']; let foundWord: boolean; // add annotation of 'boolean' // you can also initialize it like so: // let foundWorld = false; // TS will now know that foundWord is of type false for (let i = 0; i < words.length; i++) { if (words[i] === 'green') { foundWord = true; } } |
Scenario 3 – variable shows Type cannot be Inferred Correctly
1 2 3 4 5 6 7 8 9 10 |
let numbers = [-10, -1, 12]; let numberAboveZero = false; // by default false // However! if number is above zero, we want it to be assigned a number! for (let i = 0; i < numbers.length; i++) { if (numbers[i] > 0) { numberAboveZero = numbers[i]; // type inference would give error here due to default false } } |
what we could do:
1 2 3 4 5 6 7 8 9 10 |
let numbers = [-10, -1, 12]; let numberAboveZero: boolean | number = false; // However! if number is above zero, we want it to be assigned a number! for (let i = 0; i < numbers.length; i++) { if (numbers[i] > 0) { numberAboveZero = numbers[i]; // now this would be ok } } |