--- tags: blog --- # 以「陰陽」理解 TypeScript 的 Type 和 Value 🌗 ## *Value*(值) *value* 就是在執行時期,能夠在表達式中引用的變數。 例如 `let x = 5` 會建立一個叫做 `x` 的 *value*,而且可以透過 `console.log(x)` 把值印出來。 :::success 🌕 我喜歡用陰陽的**陽**來形容 *value* ::: ES6(JavaScript 本來就有的): 1. 以 `let`、`const` 和 `var` 宣告的 value 1. `function` 1. `class` 1. 引用 value 的 `import` TypeScript 特有的: 1. `enum` 1. 包含 value 的 `namespace` 或 `module` ## *Type*(型別) :::success 🌑 我會用**陰**來形容 *type*。 我們並沒辦法拿型別執行來做運算,因為它們僅僅是用來標註型別用的,且經編譯後就會丟棄這些型別的訊息。 ::: 在 TypeScript 能以下列方法建立 *type*: 1. type 例如 `type sn = number | string` 1. interface 例如 `interface I { x: number[] }` 1. class 💙 例如 `class C { }` 1. enum 💙 例如 `enum E { A, B, C }` 1. 引用 type 的 `import` ## 💙 能同時建立 *Value* 和 *Type* 的特例 1. `class` 1. `enum` 稱它們為特例的原因是,由這兩個關鍵字宣告出來的東西,同時是 *value* 也是 *type*。且不像一般的 *type*,它們經編譯後依然會被留下來。 ### `class` 範例 ```typescript= // 宣告叫做 Student 的 class class Student { name: string age: number constructor (name: string, age: number) { /* ... */ } } // 可以將 `Student` 當 value 用: // 例如透過 new 來建立一個實例 const sean = new Student('黃省喬', 24) // 也可以將 Student 當 type 用: // 例如用來宣告列表型別 `Students` type Students = Student[] // 或是當作參數的型別 const 點名 = (student: Student) => { console.log(`🙋 ${student.name}`) } 點名(sean) ``` ### `enum` 範例 ```typescript= // 宣告叫做 Status 的 enum enum Status { idle = 0, loading = 1, success = 2, failure = 3, } const isSuccess = (status: Status) => { return status === Status.success } ``` 可至 [TypeScript Playground](https://www.typescriptlang.org/play?#code/KYOwrgtgBAygLgQzmAzlA3gKClAlgEwBtgoBeKABgBpspCB7BfXEAczKgEYacUwBjfsBRpyAJh5QAZglyEwAJxLkAzDQC+mTP3ogUcPChgChIjgAp9SVAC5YiZCgCUZAHwZaS5ApBQrjslJyeGsUADo+QWEUTHUgA) 查看這段程式碼的 enum 是如何被編譯的 ## 如何打破「陰陽」的隔閡? 也就是,該如何反推某個**值**來得到它的**型別**? → **`typeof`** :::info 只能從某個 🌕 value 得到它的 🌑 type; 反過來想從 🌑 type 得到 🌕 value 則是辦不到的。(上述特例除外) ::: ```typescript= // 宣告一個物件🌕 const sushi = { name: '🍣', price: 40, isRaw: true, } // 使用 `typeof` 關鍵字取得物件的型別🌑 type Food = typeof sushi // { name: string, price: number, isRaw: boolean } // 取得 `Food` 的所有鍵的型別🌑 type KeyOfFood = keyof Food // "name" | "price" | "isRaw" // 取得 `Food` 的所有值的型別🌑 type ValueOfFood = Food[KeyOfFood] // string | number | boolean ``` :::warning ⚠️ 此處的 `typeof` 是 TypeScript 的關鍵字,注意別和 JavaScript 的運算子 `typeof` 混淆了! ::: ## 參考資料 https://www.typescriptlang.org/docs/handbook/declaration-files/deep-dive.html
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.