Type Inference
Type inference in TypeScript is the ability of the TypeScript compiler to automatically determine the type of a variable, expression, or function based on its value or usage without the need for explicit type annotations.
const name = 'Alice'; // TypeScript infers name type as string function sum(a: number, b: number) { return a + b; } // TypeScript infers return type of function sum as number
Type Alias
Type alias is simply a name for any type. It allows us define complex types in a more readable and reusable manner by using
type
keyword:type ID = numer | string; type User = { id: ID; name: string; age: number; }
Type Annotation
Type annotation is a way to explicitly specify the type of a variable, parameter or return value of a function.
const name: string = 'Alice'; function sum(nums: number[]): number => {...}
Type Intersection
Type intersection is used to combine multiple types into a single type using
&
operator. It is often used for object types.type Contact = { email: string; phone: number; } type Person = { name: string; age: number }; type Customer = Contact & Person; // Equivalent to: type Customer = { email: string; phone: number; name: string; age: number }
Type Assertion
Type assertion is used to explicitly specify a more specific type using the
as
keyword. It is helpful when TypeScript cannot determine the exact type to return, or when you want to override the type inferred by TypeScript.// Case: TypeScript does not know return type const inputElement = document.getElementById('name') as HTMLInputElement; // Case: Overriding inferred type const response = (await fetch("/api/data")) as Response;
Type Guard
Type guard is a way to narrow down the type of a variable to a specific type before you perform operations on that value.
// Using typeof operator function printLabel(code: number | string) { if(typeof code === 'number') { // TypeScript knows number is a string here console.log(code*1000); } if(typeof code === 'string') { // TypeScript knows string is a string here console.log(code.padEnd(5,'0')) } }
Type Compatibility
Type compatibility is the mechanism to check whether one type can be assigned to another without causing type errors, based on their structure and properties.
// Class interface Pet { name: string; } class Dog { name: string; } let pet: Pet; // OK, because of structural typing pet = new Dog(); // Function let x = () => ({ name: "Alice" }); let y = () => ({ name: "Alice", location: "Seattle" }); x = y; // OK y = x; // Error, because x() lacks a location property // Generic interface Empty<T> {} let x: Empty<number>; let y: Empty<string>; x = y; // OK, because y matches structure of x
Type Parameter
A type parameter is used in generics and acts as an placeholder for an actual type when a generic type, function or class is used. In the example below,
T
is an type parameter:function identity<T>(value: T): T { return value; }
Type Narrowing
Type narrowing in TypeScript is the process of refining the type of a value within a specific block of code.
// Using in operator to narrow type Fish = { swim: () => void }; type Bird = { fly: () => void }; function move(animal: Fish | Bird) { if ("swim" in animal) { return animal.swim(); } return animal.fly(); }
Type Literal
A type literal is a specific value or a set of specific values used as a type. It represents specific constants rather than general types like
string
,number
orboolean
.// String literal type type Department = 'engineer' | 'sale' | 'marketing'; // Number literal type type HttpCode = 200 | 400 | 500;
These are common terms and their practical example. I hope this article help you become more familiar with these terms when working with TypeScript.