Skip to main content

[TS] Snippets

ENUM#

假設我們的 enum 是這樣:

enum GENDER {  MALE = 'male',  FEMALE = 'female',}

把 enum 的 values 變成 union type(values of enum to type )#

Typescript: string literal union type from enum @ StackOverflow

Template Literal Types 出來之後,要把 enum 的 values 變成 union type 非常簡單:

// get type from values of enumtype valueAsUnion = `${GENDER}`; // "male" | "female"

把 enum 的 keys 變成 union type (keys of enum to type)#

// get type from keys of enumtype keyAsUnion = keyof typeof GENDER; // "MALE" | "FEMALE"

把 enum 的 values 變成 object key(values of enum to object key)#

enum GENDER {  MALE = 'male',  FEMALE = 'female',}
type valueAsKey = Record<GENDER, string>;// type valueAsKey = {//  male: string;//  female: string;// }

錯誤處理#

  • err 定義成 unknown
  • 搭配 err instanceof Error 這個 type guard
function foobar() {}
try {  foobar();} catch (err: unknown) {  if (err instanceof Error) {    console.log(err.stack);  } else {    console.log(err);  }}

解構賦值後搭配 as#

const allPostsData = fileNames.map((fileName) => {  // ...
  return {    id,    ...(matterResult.data as { date: string; title: string }),  };});

JSON type#

type JSONValue =  | string  | number  | boolean  | null  | JSONValue[]  | {      [k: string]: JSONValue;    };
const result: JSONValue = {  name: 'Aaron',  languages: ['zh-TW', 'en-US'],};

帶有預設欄位的 function options#

interface Person {  fullName: string;}
// GetPerson 這個 type 可以接收 options,預設定好的 options 包括 `firstName` 和 `lastName`// 但可以透過 T 自行添加額外的 option// 若不給 T 的話,新添加的 options value 都會是 unknowntype GetPerson<T extends Record<string, unknown> = Record<string, unknown>> = (  options: { firstName: string; lastName: string } & T,) => Person & T;
const getPerson: GetPerson<{ age: number }> = (options) => {  const { firstName, lastName, age } = options;  return {    fullName: `${firstName} ${lastName}`,    age: age,  };};
const person = getPerson({ firstName: 'Aaron', lastName: 'Chen', age: 32 });console.log(person.age);

帶有預設欄位的 object#

keywords: object, dictionary, indexed signatures#

在下面的例子中,homeoffice 會是必填的屬性,但因為使用 indexed signature / dictionary,所以可以在該物件中添加額外的屬性

/* Index Signatures or Dictionary Type */interface PhoneNumberDict {  // 因為物件的 key 可能沒有對應的 value,因此要記得加上 undefined  [numberName: string]:    | undefined    | {        areaCode: number;        num: number;      };
  // 搭配 indexed signatures 使用時,表示這兩個屬性必須存在  home: {    areaCode: number;    num: number;  };  office: {    areaCode: number;    num: number;  };}
const phoneDict: PhoneNumberDict = {  // home: {areaCode: 321, num: 333},  // 可以避免 typo  home: { areaCode: 123, num: 456 },  office: { areaCode: 321, num: 456 },
  // 因為有定義 indexed signatures,所以可以添加額外的屬性  registered: { areaCode: 666, num: 333 },};

isDefined#

const isDefined = <T>(x: T | undefined): x is T => {  return typeof x !== 'undefined';};
const foo = ['a', 'b', undefined];const stringArray = foo.filter(isDefined);