ts-checker is a series that helps you learn TypeScript from beginner to advanced, including not only the basics of ts but also detailed solutions to Type-Challenges.
Data Types#
Basic Data Types#
-
Numeric type
number
const age: number = 18
-
String type
string
const name: string = 'lybenson'
-
Boolean type
boolean
const isMale: boolean = true
-
Void
void
: commonly used when a function does not return a valuefunction printHeight(height: number): void { console.log(height) }
-
null
andundefined
-
any
: any other type is a subtype ofany
, and any type value can be assigned to a variable of typeany
const anyUse: any = { name: 'lybenson' } anyUse.name
-
unknown
: unknown type, likeany
, any type value can also be assigned to a variable of typeunknown
const unknownUse: unknown = { name: 'lybenson' } unknownUse.name // error: 'unknownUse' is of type 'unknown'.
-
never
: represents a type of value that never existsfunction error(message: string): never { throw new Error(message) }
Other Data Types#
Function Types#
When defining a function type, you need to provide parameter types and return value types
const sum = (a: number, b: number): number => {
return a + b
}
The return value type can be omitted, and ts
will automatically infer the type
Array Types#
There are mainly two types of array declarations:
const arr1: number[] = []
const arr2: Array<number> = []
Tuple Types#
Arrays are generally composed of values of the same type, but tuples can store values of different types
const student: [string, number] = ['lybenson', 18]
Enum Types#
Declared using the keyword enum
enum Direction {
NORTH,
SOUTH,
EAST,
WEST
}
const direction: Direction = Direction.SOUTH
Enum values can be omitted, starting from 0 by default
Union Types#
Union types indicate that the value of a variable can be one of multiple types, emphasizing or, connected by the |
symbol
type Roles = 'CEO' | 'CTO' | 'CFO'
const userRole: Roles = 'CTO'
Intersection Types#
Intersection types indicate that a variable has all properties of the types, emphasizing and, connected by the &
symbol
type Student = {
name: string
}
type Employee = {
name: string
salary: number
}
// UserRole has both Student and Employee properties
type UserRole = Student & Employee
const user: UserRole = {
name: 'lybenson',
salary: 3500
}
Note
If the two intersected types have the same property name but different property types, the property types will also intersect, such as:
type Student = {
name: number
}
type Employee = {
name: string
salary: number
}
// name types are different, so the types will intersect
type UserRole = Student & Employee
// {
// name: number & string
// salary: number
// }
// Error: No value can have both number and string types
const user: UserRole = {
name: 'lybenson',
salary: 3500
}
Optional Types#
Optional types are not a specific type but a type generic.
Using ?
indicates that when declaring a variable type or function parameter type, a type is specified, but it is not required for that variable or parameter to have a value. Essentially, it adds undefined
to the original type
function printName(firstName: string, lastName?: string) {
if (lastName) {
console.log(firstName + ' ' + lastName)
} else {
console.log(firstName)
}
}
// lastName is optional and can be omitted
printName('lybenson')
// Define optional properties in custom types
type Employee = {
name: string
salary?: number
}
const emp: Employee = {
name: 'lybenson'
}
-?
makes the property non-optional.
Readonly Types#
Readonly types are also not a specific type.
Using readonly
indicates that the property is read-only and cannot be modified
// Define name property as read-only
type Employee = {
readonly name: string
salary?: number
}
const emp: Employee = {
name: 'lybenson',
salary: 3500
}
emp.name = 'jack ma' // Cannot assign to 'name' because it is a read-only property.
-readonly
makes the property non-readonly.
Custom Types#
Custom types commonly use type
and interface
, the difference between them is
type
defines union types, intersection types, tuple types, function types, etc. Typically used to create complex type combinationsinterface
is commonly used to define the structure of object types. Inheritance and other features can be used
type
#
type User = {
name: string
age: number
sex?: number
}
type Status = 'draft' | 'published'
interface
#
interface User {
name: string
age: number
sex?: number
getName: () => string
}
Note
Types defined with the same name using interface
will automatically merge, such as:
interface User {
name: string
}
interface User {
age: number
}
// The automatically merged type is
interface User {
name: string
age: number
}
Type Conversion#
as
#
// Force conversion to any
const distance: number = '100000' as any
as const
treats the value as an immutable constant rather than a mutable variable
const name = 'lybenson' as const
The type of name
is 'lybenson'
, not string
If it is an object type:
const user = {
name: 'lybenson',
age: 18
} as const
Without using as const
, the type of user
will be inferred as
const user: {
name: string
age: number
}
After using as const
, the type of user
will be inferred as
const user: {
readonly name: 'lybenson'
readonly age: 18
}
<T>
#
T
is the type to be converted
const distance: number = <any>'100000'
Built-in Type Declarations#
Built-in types can help us define types more conveniently, for example, Omit
can remove properties from an object
interface User = {
name: string
age: number
sex?: number
salary: number
workTime: number
}
// The Student type is the User type with the fields salary and workTime removed
type Student = Omit<User, 'salary' | 'workTime'>
See the complete table below
Type Name | Description |
---|---|
Partial<T> | Makes all properties in T optional |
Required<T> | Makes all properties in T required |
Readonly<T> | Makes all properties in T readonly |
Pick<T, K extends keyof T> | Selects a set of properties from T , the selected properties are in K |
Record<K extends keyof any, T> | Constructs an object type with property name type K and property type T . For example, type obj = Record<string, any> |
Exclude<T, U> | Excludes types contained in U from the union type T |
Extract<T, U> | Extracts types contained in U from the union type T |
Omit<T, K extends keyof any> | Excludes properties in K from T |
NonNullable<T> | Excludes null and undefined from type T |
Parameters<T extends (...args: any) => any> | Extracts parameter types from function type T and returns a tuple type composed of parameter types |
ReturnType<T extends (...args: any) => any> | Extracts and returns the return value type of function type T |
InstanceType<T extends abstract new (...args: any) => any> | Extracts and returns the type of the instance of constructor function type T |
Uppercase<S extends string> | Converts all characters in string type S to uppercase and returns a new string type |
Lowercase<S extends string> | Converts all characters in string type S to lowercase and returns a new string type |
Capitalize<S extends string> | Converts the first character of string type S to uppercase |
Uncapitalize<S extends string> | Converts the first character of string type S to lowercase |
ThisType<T> | Specifies the type of the this keyword in a method |