跳至主要内容

[掘竅] TypeScript

判斷某個型別參數是否是 never

type IsNever<T = never> = [T] extends [never] ? true : false;

type Foo = IsNever; // true
type Bar = IsNever<string>; // false

這是一個滿有趣的應用,要判斷某個型別是不是 never 需要使用 tuple 的方式。

如果寫成下面這樣,因為 never 是空集合,所以當 never extends never 時,不是 true 也不是 false,而會是 never

// 因為 never 是空集合,所以結果不會
type IsNever<T = never> = T extends never ? true : false;

type Foo = IsNever; // never
type Bar = IsNever<string>; // false

這就類似,當 any extends string 時可能是 true 也可能是 false,最終會得到 boolean:

type T1 = any extends string ? true : false; // boolean

忽略掉 TS 的錯誤

// @ts-expect-error
// 意思是我認爲這裡 ts 應該會覺得有錯,而我要把它忽略
// 當 ts 發現下面這行並沒有檢查到錯誤時,會跳出提示

// @ts-ignore
// 意思是不管這裡有沒有錯,ts 都不要理他

ignore-ts-error

...args: never[] 的意思

Understanding (...args: never[]) => ... in TypeScript Handbook @ reddit

白話翻譯指的是能夠接收任何型別作為參數的函式(沒有帶參數也可以)。

handle modules without type definition

Using a JavaScript library (without type declarations) in a TypeScript project. @ medium

處理問題:Cannot find module '@mono-sandbox/a' or its corresponding type declarations.

Cannot find module

定義一支 foobar.d.ts,在裡面宣告該 package:

// ./misc.d.ts
declare module '@mono-sandbox/a';
declare module '@mono-sandbox/b';

接著在 tsconfig.json,記得要在 include 中包含到這支檔案:

// tsconfig.json
{
"include": ["src", "misc.d.ts"]
}

Array.prototype.map

map<T> 後放入的 T 表示的是 map 回傳後 item 的型別:

// https://tsplay.dev/mxor7N
const data = [
{ firstName: 'Aaron', lastName: 'Chen' },
{ firstName: 'PJ', lastName: 'Chen' },
];

type Name = string;

const result = data.map<Name>((item) => {
return `${item.firstName} ${item.lastName}`;
});

console.log(result);

Error Handling in Catch Clause

在 TS 4.0 之後,如果使用 strict mode 或有啟用 useUnknownInCatchVariables 的設定,try...catch... 中,catch(err) 中的 err 會從原本的 any 改成 unknown,因此,如果你要使用 JS 中 error 物件中預設就有的屬性,需要先使用 instance of 來確保它是 Error 型別:

try {
// ...
} catch (err) {
// We have to verify err is an
// error before using it as one.
if (err instanceof Error) {
console.log(err.message);
}
}

變數後的驚嘆號(non-null assertion)

In Typescript, what is the ! (exclamation mark / bang) operator when dereferencing a member?) @ Stack Overflow

在變數後使用驚嘆號,是告訴 TypeScript 説這個變出不會是 nullundefined,要記得這是一個 "assertion",和 as 是一樣的意思。

x!; // 告訴 TS,x 這個變數不會是 null 或 undefined

Giscus