TypeScript - 使用筆記 (2)

關於物件型別

TypeScript - 使用筆記 (2)

1. Array

  • 在前面寫基本類型 + [ ],表示陣列內的值都會是這個類型
const arrString: string[] = ['hello', 'world']
const arrBoolean: boolean[] = [true, false, true]
const arrNumber: number[] = [1, 2, 3, 4]

// 宣告空陣列
const names: string[] = []
names.push('data1')
names.push(1) // error: Argument of type 'number' is not assignable to parameter of type 'string'
  • 使用陣列泛型(Array Generic) Array<elemType> 來表示陣列
// 宣告陣列內的值都是number型別
const arrNumber2 : Array<number>

2. Tuple

  • Tuple通常是指一個資料結構,可儲存多個不同型別項目
  • 所指定的型別跟給予的資料型別與個數必須相等
  • 當陣列長度不變時可以使用
// example1
const tuple: [boolean, number, string] = [true, 10, 'ABC']

// example2
const tup: [string, number, boolean] = ['Fin', 77, false]
tup[0] = 'Bill'
tup[1] = 44
tup[3] = 123 // error Tuple type '[string, number, boolean]' of length '3' has no element at index '3'.

// example3
let student: [string, number]
student = ['Ken', 99]
  • with spread operator
  • 必須先用tuple宣告陣列內哪個東西是哪個類型
let values: [string, string, number]
values = [tofrom.value, details.value, amount.valueAsNumber]
if (type.value === 'invoice') {
  doc = new Invoice(...values)
} else {
  doc = new Payment(...values)
}

3. Object

  • { } 內指定物件中可以包含哪些屬性
let songList: object
songList = { type: 'JPOP', num: 88 }

let movies: {
  name: string
  year: number
  type: string
}
  • 無法新增一開始沒有宣告的屬性
let ninja = {
  name: 'mario',
  hat: 'red',
  age: 30,
}

ninja.skills = ['flying', 'jumping'] // error
  • 在屬性名稱加上? 表示可選屬性
let dog: { name: string; color?: string }
dog = { name: 'dodge' } // ok
  • 可以擴充任意類型的值
let a: { name: string; [propName: string]: any }
a = { name: 'Ben', age: 28, gender: 'secret' }

4. Function

  • 可以定義參數的類型
  • 可以定義回傳值的類型
  • 參數如果要放?或是預設值(可選),要放在最後面
let greet: Function

greet = 'hello' //error

greet = () => {
  console.log('hello')
}
const add = (a: number, b: number, c: number | string = 10) => {
  console.log(a + b)
}

add(5, 10)

const minus = (a: number, b: number) => {
  return a - b
}

// 會自動鎖定型別成數字
let result = minus(10, 7)
result = 'str' // error
  • 規定回傳值的型別,可以在()後加上:
const nothingHere = (): void => {
  console.log('沒有回傳值')
}
const add(a:number, b:number):number {
	return a + b
}
// example 1
let greet: (a: string, b: string) => void

greet = (name: string, greeting: string) => {
  console.log(`${name} says ${greeting}`)
}
// example 2
let calc: (a: number, b: number, c: string) => number

calc = (numOne: number, numTwo: number, action: string) => {
  if (action === 'add') {
    return numOne + numTwo
  } else {
    return numOne - numTwo
  }
}
// example 3
let logDetails: (obj: { name: string; age: number }) => void

type person = { name: string; age: number }

logDetails = (ninja: person) => {
  console.log(`${ninja.name} is ${ninja.age} years old`)
}

const myNinja: person = { name: 'John', age: 25 }
logDetails(myNinja)

void

  • 表示函式沒有回傳值
function myFn(): void {
  return
}

函式作為參數時

  • callback函式接受一個string參數,沒有回傳值
function request(callback: (result: string) => void) {
  callback('success')
}

request((result) => console.log(result))

// 使用type 簡化
type RequestCallback = (result: string) => void

function request(callback: RequestCallback) {
  callback('success')
}

5. Enums

  • 用來新增同系列的常數(不可修改的變數)
  • 在多個固定值之間選擇時使用
enum Days {
  Sun,
  Mon,
  Tue,
  Wed,
  Thu,
  Fri,
  Sat,
}
enum Gender {
  Male,
  Female,
}

let i: { name: string; gender: Gender }
i = {
  name: 'Andy',
  gender: Gender.Male,
}

列舉數字

  • 可以自行手動賦值,未手動賦值的列舉項會接著上一個列舉項遞增
enum CardinalDirections {
  North = 1,
  East,
  South,
  West,
}
// logs 1
console.log(CardinalDirections.North)
// logs 4
console.log(CardinalDirections.West)
  • 可以自行指定特定數字
enum StatusCodes {
  NotFound = 404,
  Success = 200,
  Accepted = 202,
  BadRequest = 400,
}
// logs 404
console.log(StatusCodes.NotFound)
// logs 200
console.log(StatusCodes.Success)

列舉字串

enum CardinalDirections {
  North = 'North',
  East = 'East',
  South = 'South',
  West = 'West',
}
// logs "North"
console.log(CardinalDirections.North)
// logs "West"
console.log(CardinalDirections.West)
  • 在ResourceType加入enum
enum ResourceType {
  BOOK,
  AUTHOR,
  FILM,
  DIRECTOR,
  PERSON,
}

interface Resource<T> {
  uid: number
  resourceName: ResourceType
  data: T
}

const docTwo: Resource<object> = {
  uid: 0,
  resourceName: ResourceType.BOOK,
  data: { name: 'Hear the Wind Sing' },
}

const docThree: Resource<object> = {
  uid: 1,
  resourceName: ResourceType.PERSON,
  data: { name: 'Yong' },
}

常數列舉

  • 使用 const enum 定義的列舉型別
  • 會在編譯過程中被完全擦除,並且會將所有使用到 const enum 成員的地方用其實際值替代

example1:

//比直接使用0和1更好理解
const enum DIRECTION {
  UP,
  DOWN,
}

const direction = ref<DIRECTION>()

direction.value = DIRECTION.UP

// 編譯後
var direction = 0

example2:

const enum Directions {
  Up,
  Down,
  Left,
  Right,
}

let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]

//編譯後
var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */]