This produces a type that has both Quckable and Flyable properties.
type Duck = Quckable & Flyable;
Union Types
type Flyable = Eagle | Butterfly;
This produces a type that has the overlap properties of Eagle and Butterfly.
Custom Type Guards
If you do not want to cast a type as string but have some custom logic to see if an object belongs to a type then you can do;
const canFly = (animal: Animal): animal is Flyable =>
typeof (animal as any).fly === "function";
if (canFly(animal)) {
animal.fly();
}
animal is Flyable is a boolean, this is a safer cast.
Type assertion
Used when you know the value is not null | undefined
person.children[0]!.name;
Literal Types
Since types are sets you can use literal types, that is a set of one value.
type Move "rock" | "Paper" "Scissor";
Never return functions
const throws =(): never => {
throw new Error("This never returns");
}
const loops = (): never => {
while (true) {
console.log("This never returns either");
}
}
Using unknown over any
If the user is inputting a value and you do not know what it is. You should use unknown.
let a: string;
let x: any;
a = x; // Compiles
x = a; // Compiles
let y: unknown;
y = a; // Compiles
a = y; // Does not compile
Using unknown allows you to avoid assigning a: string to the value of y: unknown since y is unknown. If you use x: any then this will not be caught.
Index Types
type Duck {
colors: string;
feathers: number;
}
type DuckProps = keyof Duck; // = "colors" | "feathers"
type ColorType = Duck["colors"]; // = string
type DuckValues = Duck[DuckProps] // = string | number
Here keyof gives the set of possible keys on the interface.
Conditional Types
This allows us to have assign different types based on the input T being a boolean or not.
type StringOrNumber<T> = T extends boolean ? string : number;
type T1 = StringOrNumber<true>; // string
type T2 = StringOrNumber<false>; // string
type T3 = StringOrNumber<Object>; // number
Example
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
type T0 = TypeName<string>; // "string"
A simpler version of the above would be.
type TypeName<T> = nameof(T);
If restricting to just the above types
type TypeName<T> =
["string", "number", "boolean", "undefined", "Function"]
.includes(nameof(T));
``
## Infer
`infer` Is a specific key word that you can use within a conditional type and is used on the right side of `extends`.
```ts
type ElementType<T> = T extends (infer U)[] ? U : never;
type T = ElementType<[]>; // = never
type T1 = ElementType<string[]>; // = string
If T is an array of U then resolve to the type U.
Functional Programming
The principle of separating the data structures from the objects. An object is a class that has functions and methods while the data structure is an object that represents pure data.
One step further is we don't need objects, most of the time. We just need functions that do work on those data structures.
Intersection Types
This produces a type that has both
Quckable
andFlyable
properties.Union Types
This produces a type that has the overlap properties of
Eagle
andButterfly
.Custom Type Guards
If you do not want to cast a type
as string
but have some custom logic to see if an object belongs to a type then you can do;animal is Flyable
is a boolean, this is a safer cast.Type assertion
Used when you know the value is not
null | undefined
Literal Types
Since types are sets you can use literal types, that is a set of one value.
type Move "rock" | "Paper" "Scissor";
Never return functions
Using unknown over any
If the user is inputting a value and you do not know what it is. You should use
unknown
.Using unknown allows you to avoid assigning
a: string
to the value ofy: unknown
since y is unknown. If you usex: any
then this will not be caught.Index Types
Here keyof gives the set of possible keys on the interface.
Conditional Types
This allows us to have assign different types based on the input
T
being aboolean
or not.Example
A simpler version of the above would be.
If restricting to just the above types
If
T
is an array ofU
then resolve to the typeU
.Functional Programming
The principle of separating the data structures from the objects. An object is a class that has functions and methods while the data structure is an object that represents pure data.
One step further is we don't need objects, most of the time. We just need functions that do work on those data structures.