ちょっとした技術メモを忘れないうちに書いていく

TypeScript 型変換を補助するユーティリティ型

2022-01-20

いまさらながらTypeScriptに入門


Partial<T> プロパティを任意に変換する

型引数Tに指定された型のプロパティを任意(?:)に変換する

interface Person{
  name:string;
  age:number;
}
//Personではプロパティが必須のためエラーとなる
// let valA:Person={};

// Partialを使ってPersonを任意型にする
type PersonOption = Partial<Person>;

//任意型のためageがなくてもOK
let valB:PersonOption={
  name:'YOSHIO'
}

Required<T> プロパティを必須に変換する

型引数Tに指定された型のプロパティを必須に変換する

// Personを任意プロパティで定義
interface Person{
  name?:string;
  age?:number;
}

let valA:Person={};//Personは任意型なので何なくてもOK

// Requiredを使ってPersonを必須型にする
type PersonRequired = Required<Person>;

// let valB:PersonRequired={}//プロパティが必須に変わったのでエラー

Readonly<T> プロパティを読み取り専用に変換する

型引数Tに指定された型のプロパティを読み取り専用に変換する

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

// Readonlyを使い読み取り専用に変換する
type PersonArticle = Readonly<Person>;

let valA:PersonArticle = {
  name:'YOSHIO',
  age:21
};

// valA.name = 'MARUO';//読み取り専用なのでエラー

Record<K, T> 指定された型をプロパティを持つオブジェクト型を定義

型引数Kで指定されたプロパティを持つ型を生成する、生成されたvalueは型引数Tの型になる

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

// キーをリテラル値、value値をPerson型で指定
let MyPerson : Record<'YOSHIO'|'MARUO'|'HUMIKO',Person> = {
  YOSHIO:{name:'よしお', age:93},
  MARUO:{name:'まるお', age:15},
  HUMIKO:{name:'ふみこ', age:110},
  // TETSUO:{name:'てつお', age:110}, // 「TETSUO」がキーに指定されていないためエラー
  // MARUO:{name:'まるお', age:15}, // MARUOは定義済みなのでエラー
}

Pick<T, K> 既存の型から特定のプロパティを抽出する

既存の型Tから、型引数Kを抽出する


interface Book{
  isbn:number;
  title:string;
  price:number;
  published:Date;
}

//Bookからtitle、priceを抽出した型を生成
type PickBook = Pick<Book, 'title'|'price'>;
let pick:PickBook = {
  title:'タイトル',
  price:2300
}
//type PickBook2 = Pick<Book, 'test'>;//存在しないプロパティを指定するとエラー

Omit<T, K> 既存の型から特定のプロパティを除去する

既存の型Tから、型引数Kを除去する


interface Book{
  isbn:number;
  title:string;
  price:number;
  published:Date;
}

// Bookからisbn、publishedを除去した型を生成
type OmitBook = Omit<Book, 'isbn'|'published'>;
let pick2:OmitBook = {
    title:'タイトル',
    price:2300
}

type OmitBook2 = Omit<Book, 'test'>;//存在しないプロパティを指定してもエラーにはならない

Extract<T, U> 共用型から特定の型を抽出する

型引数Tと型引数Uに共通する型を抽出する

type TestFunc = () => void;
// 共用型TestTypeを定義
type TestType = string|number|boolean|TestFunc;

// TestTypeとstring|number[]に共通する型を生成(結果string)(numberとnumber[]は違う)
type NewType = Extract<TestType, string|number[]>
let valB:NewType;
valB= 'AAA';

Exclude<T, U> 共用型から特定の型を除去する

型引数Tから型引数Uを除外する

type TestFunc = () => void;
// 共用型TestTypeを定義
type TestType = string|number|boolean|TestFunc;

// TestYypeからstring|booleanを除去した型を生成(結果number|TestFunc型)
type NewType1 = Exclude<TestType, string|boolean>;
let valA:NewType1 = 3;
// // 関数すべて除く場合は「Function」を指定(結果string|number|boolean型)
type NewType2 = Exclude<TestType, TestFunc>;
type NewType3 = Exclude<TestType, Function>;

NonNullable<T> null,undefinedを除去する

// TestTypeからnull、undefinedを除いたNewType3を生成(結果string|number)
type TestType = string|number|null|undefined;
type NewType = NonNullable<TestType>;

Parameters<T>、ReturnType<T> 関数の引数/戻り値をもとに型を生成する

  • Parameters:与えられた関数の引数をもとにタプル型を生成する
  • ReturnType:与えられた関数の戻り値の型を生成する

function testTunc(str:string, boo?:boolean): string|number {
  return 1;
}

//testTuncの引数をタプル型で取得([string, (boolean | undefined)?])
type Args = Parameters<typeof testTunc>
let valA:Args =["文字列", true];//trueは任意

//testTuncの戻り値型をタプル型で取得(string | number)
type Re = ReturnType<typeof testTunc>
let valB:Re = 2;//[number|string]

// 関数を実行しやすい?
valB = testTunc(...valA);

/** オーバーロードの戻り値はうまく取れない? */
function test(params: number): number;
function test(params: string): string;

function test(params: any): any {
if (typeof params === 'number') {
  return params;
} else if (typeof params === 'string') {
  return params;
}
}
// TestTypeはstring型になる
type TestType = ReturnType<typeof test>;

ConstructorParameters<T> 与えられたクラスのコンストラクタの型を生成

コンストラクタの引数をもとにタプル型を生成する


class Book{
  _title:string;
  _price:number;
  constructor(title:string, price:number){
      this._title = title;
      this._price = price;
  }
}
//Bookのコンストラクタの引数をもとにタプル型を生成([string, number])
type Con = ConstructorParameters<typeof Book>;
let valA:Con = ["本のタイトル", 2300];

let book = new Book(...valA);