changed 4 years ago
Published Linked with GitHub

TS 樂趣無窮

Sean Huang / 2021-08-10

Interface 不加前綴 I 的理由

→ TS 本身就已達成標注型別的目的


額外的心智負擔

// 如果帕斯卡命名法對你來說合理... interface IUser { name: string } // 那何不也這麼做? const SName = 'Sean' // "S" for String const NAge = 18 // "N" for Number const AFriends = [/*...*/] // "A" for Array

interfacetype

若前綴 I 僅是為了註明它是個 Interface


🌰
分別以不同的方式宣告型別 User

// A. interface IUser { name: string } interface IUser { age: number }
// B. type TUser = { name: string, age: number }
// C. type RUser = Record<'name', string> & Record<'age', number>

此例中,IUserTUserRUser 三者完全等價

interface 宣告的那個並沒比較特別

這三個甚至都可被 implements
https://pse.is/不騙你


TypeScript 是🦆鴨子型別
(Duck Typing)

當看到一隻鳥走起來像🦆、
游泳起來像🦆、
叫起來也像🦆,
那麼這隻鳥就可以被稱為🦆


無需擔心型別和變數
會命名衝突

型別總是以大駝峰命名

type User = { 
  name: string, 
  age: number,
}

而變數總是以小駝峰命名

const user: User = { 
  name: 'Sean', 
  age: 23,
}

建議避免型別 MUI 組件撞名

→ 容易混淆,一時難以分辨它是組件或是型別


🌰

import Dialog from '@material-ui/core/Dialog' interface Dialog { // ^^^^^^ 🥲 'Dialog' is already defined 'delete': DialogContent, 'deleteForbidden': DialogContent, 'deactivate': DialogContent, }

interface DialogContents { /*...*/ } // 👍

建議型別變數命名高度相關


🌰
MUI 的 Pagination 組件(節錄)

// @material-ui/lab/Pagination/Pagination.d.ts interface PaginationProps { color?: 'primary' | 'secondary' | 'standard' } function Pagination( props: PaginationProps ): JSX.Element;

變數名 型別名
props PaginationPropsProps
state DialogStateState

💡 可根據上下文
自行決定是否省略修飾語


請直接向套件拿型別


🌰(節錄)

const handleClose = ( event?: React.SyntheticEvent, // 🤔 reason?: string // 😑 ) => { /* ... */ }
<Snackbar onClose={handleClose} />

怎麼找?


運氣好的話
你會看到這個已匯出的型別定義


匯入

import Snackbar, { SnackbarProps } from '@material-ui/core/Snackbar'

指定 handler 的型別

const handleClose: SnackbarProps['onClose'] = ( event, // React.SyntheticEvent<any, Event> reason, // SnackbarCloseReason ) => { /* ... */ }

🎉 得到符合組件要求的參數型別

<Snackbar onClose={handleClose} />

解決日益增長的 src/constants/type.ts

→ 抽出型別成獨立檔案並置於 src/types

例如 Controller.tsModel.ts

K7 建議:目錄結構請參考 container 和 component


關於混搭 BS 和 MUI 樣式

→ 只用 BS 的網格相關 class 如 .row.col.container 等;
其餘用 MUI 的組件如 <Box />


參考資料

Select a repo