TypeScript

Node.js TypeScript

環境

安裝

TypeScript

npm install typescript --save-dev
yarn add typescript

ts-node

npm install -g ts-node
yarn add ts-node

初始化

tsc --init

tsconfig.json

{
  "compilerOptions" : {
    // 目標語言: es6, es2015, es2016, es2017, es2018, es2019, es2020
    "target" : "es5",
    "module" : "commonjs",
    // 產生對應原始檔
    "sourceMap" : true,
    "inlineSourceMap" : true,
    // 輸出 js 檔案目錄
    "ourDir" : "./dist",
    // 來源目錄
    "rootDir" : "./src",
    // 移除註解
    "removeComments": true,
    // 不產生 js 檔案
    "noEmit" : true,
    // 錯誤不產生 js 檔案
    "noEmitOnError" : true,

    // 檢查不能有沒有使用的區域變數
    "noUnusedLocals" : true,
    // 檢查不能有沒有使用的函式參數
    "noUnusedParameters" : true,
    // 檢查不能有沒有沒確回傳資料
    "noImplicitReturns" : true,
  },
  // 排除編譯的目錄檔案
  "exclude" : [
    "test.ts",
    "*.dev.ts",
    "**/*.dev.ts",
    "node_modules",
  ],
  // 要編譯的目錄檔案
  "include" : [
    "app.ts",
  ]
}

立即執行 TypeScript

需要安裝 ts-node 套件

# 直接執行 typescript 檔案
ts-node app.ts

編譯

# 編譯 typescript 檔案
tsc app.ts
# 編譯 typescript 檔案,並監看是否有異動自動重新編譯
tsc app.ts --watch
tsc app.ts --w

變數類型

類型 說明
number 整數
string 字串
boolean 布林值
object 物件
array 陣列
Tuple 陣列規則
enum 列舉
any 不限制,很少用,除非 debug
unknown 未知
Function 函式

回傳值

類型 說明
void 空值
never 不回傳

定義變數

let addNumber: Function;
let addNumber: (a: number, b: number) => number;
let num: number;
let name: string = 'KJ';
let name: string | number = 'KJ';
let n: null = null;
let nn: undefined = undefined;
let test: any;
let arr: string[] = ['a', 'b'];
let arr: string[][] = [['a', 'b']];
let tup : [number, string, boolean] = [1, 'a', true]
let tup : [string, string][] = [['a', 'b'], ['c', 'd']]

定義函式傳入及回傳參數

function printNumber(num: number): void {
  console.log(`Result: ${num}`);
}

function addAndCallback(num1: number, num2: number, cb: (num: number) => void) {
  const result = num1 + num2;
  cb(result);
}

// num2 有加 ?,所以表示可傳可不傳
function printNumber(num: number, num2?: number): void {
  console.log(`Result: ${num}`);
}

列舉類型 enum

會產生自訂的變數,但覺得還是少用比較好,執行比較沒有效率,用 JavaScript const 變數解決這個問題就好

enum Role {
  ADMIN,
  READ_ONLY,
  AUTHOR
}

enum Role {
  ADMIN = '33',
  READ_ONLY = '44',
  AUTHOR = '55',
}

// 使用 Enum 變數
if (user.role == Role.ADMIN) {

}

自訂類型

type MyCustomType = number;
type MyCustomType = number | string;
type MyCustomType = 'Kay' | 'Jay';

function(num: MyCustomType) {

}

Interface

可以擴充的 Type

interface Employee {
  name: string;
  age: number;
}

interface Employee {
  // ? 允許 undefined
  desc?: string;
}

class 實作 interface

interface CarProps {
  name: string
  age: number
}

class Car implements CarProps {
  name: string
  age: number

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

Object

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

const obj : Employee = {
  name: 'KJ',
  age: 17,
};

斷言 as unknown

定義後端 API 回傳資料格式

type Data = {
  userId: number,
  id: number,
  title: string,
  completed: boolean
}


async getData = () => {
  const res = await fetch('https://jsonplaceholder.typicode.com/todos/1');
  const data = await res.json() as Data;
}
const data1 = Data {
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
};

type Beta = {
  name: string
}

const beta = data1 as unknown as Beta;

Class

  • private
  • public
  • protected
class Live {
  public roomName: string
  private id: string
  protected name: string

  constructor( room_name: string, room_id: string, holder_name: string) {
    console.log('建立直播');
    this.roomName = room_name;
    this.id = room_id;
    this.name = holder_name;
  }
}

const live = new Live('LOL 直撥', '001', 'Kay');
console.log(live);
class LolLive extends Live {
  constructor( room_name: string, room_id: string, holder_name: string) {
    super(room_name, room_id, holder_name);
  }

  start() {

  }
}

const LolLive = new LolLive('LOL 直撥 2', '002', 'Jay');

私有變數

class GameLive {
  //  私有變數
  #name
  constructor (name : string) {
    this.#name = name;
  }
}

泛型

function print<T> (data: T) {
  console.log('data', data);
}

print<number>(777);
print<string>('KJ');
print<boolean>(true);
class Print<T> {
  data: T
  constructor(d: T) {
    this.data = d;
  }
}

const p = new Print<number>(999)
const p = new Print<string>('KJ')

參考資料

官方

研究

教學影片

套件


React 整合

Node.js TypeScript 與 React 整合

Utility 工具

Node.js TypeScript Utility 工具

常見問題

Node.js TypeScript 常見問題