這篇來簡單筆記一下 TypeScript 中常用到的 types,以及常見的資料結構要怎麼用 type 來表示。
Table of Contents
1. Primitives
1.1 string
const str: string = 'Hello World'
1.2 number
const num1: number = 24
const num2: number = 3.14
1.3 boolean
const bool: boolean = true
1.4 bigint
const oneHundred: bigint = BigInt(100)
1.5 symbol
- Symbols are immutable, and unique.
let sym2 = Symbol("key")
let sym3 = Symbol("key")
sym2 === sym3
// false, symbols are unique
declare const sym1: unique symbol
class C {
static readonly StaticSymbol: unique symbol = Symbol()
}
2. Arrays
2.1 Array
Array
用來表示一般常用的 array,基本上就是所有 element 的 type 都是一樣的
const arr1: number[] = [1, 2, 3]
const arr2: Array<number> = [4, 5, 6]
interface NumberArray {
[index: number]: number
}
const arr3: NumberArray = [7, 8, 9]
2.2 ReadonlyArray
ReadonlyArray
用來表示這個 array 是 readonly 的,如果要 reassign 任何 element 都會噴錯
const weekDays: ReadonlyArray<string> = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
weekDays[0] = 'Sunday'
// Error! Index signature in type 'readonly string[]' only permits reading.
2.3 Tuple
tuple 並不是一個 type,而是用來明確指定這個 array 有幾個 element 以及每個 element 的 type,因此 tuple 可以用來表示 element 中有不同 type 的 array
const pair: [number, string] = [123, 'world']
// 也可以用來表示有同樣 type element 的 array
const pair: [string, string] = ['hello', 'world']
tuple 可以允許 optional property
type Coord = [number, number, number?]
function setPosition(coord: Coord) {
const [x, y, z] = coord
}
// const x: number
// const y: number
// const z: number | undefine
tuple 也可以和 rest operator 搭配使用
type StringNumberBooleans = [string, number, ...boolean[]]
// 第一個 element type 會是 string
// 第二個 element type 會是 number
// 剩下的 element type 會是 boolean
const a: StringNumberBooleans = ["hello", 1]
const b: StringNumberBooleans = ["beautiful", 2, true]
const c: StringNumberBooleans = ["world", 3, true, false, true, false, true]
type StringBooleansNumber = [string, ...boolean[], number]
// 第一個 element type 會是 string
// 中間的 element type 會是 boolean
// 最後一個 element type 會是 number
type BooleansStringNumber = [...boolean[], string, number]
// 倒數第二個以前的 element type 會是 boolean
// 倒數第二個 element type 會是 string
// 最後一個 element type 會是 number
2.4 readonly tuple
在 tuple 前面加上 readonly,會讓這個 tuple 不能 reassign 任何 element
const pair: readonly [string, number] = ['Hello', 123]
pair[0] = 'world'
// Error! Cannot assign to '0' because it is a read-only property.
也可以用 as const 來表示:
const pair = ['Hello', 123] as const
pair[0] = 'world'
// Error! Cannot assign to '0' because it is a read-only property.
3. Functions
3.1 function 內部的 type
- Parameter Type Annotations
用來標示 parameter 的 type
function greet(name: string) {
console.log("Hello, " + name.toUpperCase() + "!!");
}
greet(42);
Argument of type 'number' is not assignable to parameter of type 'string'.
- Return Type Annotations
用來標示 function return value 的 type
function getFavoriteNumber(): number {
return 26;
}
// functions which return promises
async function getFavoriteNumber(): Promise<number> {
return 26;
}
3.2 Type Alias
通常用 Function Type Expressions 的方式來表示,語法類似 arrow function
type GreetFunction = (a: string) => void
function greeter(fn: GreetFunction) {
fn("Hello, World")
}
function printToConsole(s: string) {
console.log(s)
}
greeter(printToConsole)
3.3 interface
當 function 上有其他 property 時,我們可以用物件的方式 (interface 或 type alias) 來表示
interface DescribableFunction {
description: string
(someArg: number): boolean
}
function doSomething(fn: DescribableFunction) {
console.log(fn.description + " returned " + fn(6))
}
function myFunc(someArg: number) {
return someArg > 3
}
myFunc.description = "default description"
doSomething(myFunc)
3.4 Generic Functions
有時候 function 不會知道 parameter 會以什麼 type 傳進來,這時候可以用 generic 來將 type 作為變數傳進 function
function firstElement<T>(arr: T[]): T | undefined {
return arr[0]
}
console.log(firstElement([1, 2, 3]))
4. Object Types
4.1 Type Alias
type alias 有點像是將 type 作為變數重複使用,因此也可以用來表示 object 的 type
type User = {
name: string
age: number
isAdult: boolean
}
const user: User = {
name: 'Jimmy',
age: 20,
isAdult: true
}
const getUserName = (user: User) => {
return user.name
}
4.2 Interface
interface 也可以用來表示 object 的 type,和 type alias 的語法很類似,差別在於不需要 =
interface User {
name: string
age: number
isAdult: boolean
}
const user: User = {
name: 'Jimmy',
age: 20,
isAdult: true
}
const getUserName = (user: User) => {
return user.name
}
4.3 Object 內部
const obj1: { name: string, age: number } = { name: 'Jimmy' }
// Property 'age' is missing in type '{ name: string; }' but required in type '{ name: string; age: number; }'
const obj2: { name: string, age: number } = { name: 'Jimmy', age: 20 }
// ok
- Optional Properties
- 在 property name 後加上
?
,代表這個 property 對這個 object 來說,是 optional 的
- 在 property name 後加上
const obj1: { name: string, age?: number } = { name: 'Jimmy' }
- readonly Properties
- 在 property 前面加上 readonly 這個 keyword,用來表示這個 property 不能更改
interface User {
readonly name: string
age: number
isAdult: boolean
}
const user: User = {
name: 'Jimmy',
age: 20,
isAdult: true
}
user.name = 'Jack'
// Error! Cannot assign to 'name' because it is a read-only property.
- index signatures
- 用來表示 key value 的 type,不過 js 的 object key 都會被轉成 string,所以通常 key 的部分都會是 string,如果是 number 的話,通常是用來表示 array
interface User {
age: number
[index: string]: number
}
const user: User = {
age: 20,
name: 'Jimmy'
// Error! Type 'string' is not assignable to type 'number'.ts(2322)
// object.ts(3, 3): The expected type comes from this index signature.
}
// 用來表示 array
interface StringArray {
[index: number]: string
}
const classmates: StringArray = ['Jimmy', 'Jack']
5. 參考資料
Documentation – Everyday Types
Documentation – More on Functions
Documentation – Object Types
如果覺得我的文章有幫助的話,歡迎幫我的粉專按讚哦~謝謝你!