0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【TS】型について

Last updated at Posted at 2024-12-17

interface

interfaceは基本オブジェクトにしか使わない。けど関数の型も作ることができる。

// オブジェクトのみで利用可能
interface Person {
  name: string;
  say(msg:string):void;
}

// エラー
interface func = (num:number) => void;

// エラーにならず関数の型として使える
// この書き方をコールシグネチャという
interface func {
    (num:number):void;
}

// けど、関数の型定義はタイプエイリアスの方が分かりやすいので、こっちを使う
type func = (num: number) => void;

継承

// これはどちらも同じ意味

interface A extends B {
  name: string;
}

type A = {
  name: string;
} & B

同名だけど型が違う場合の継承

//interface
interface Nameable {
  name: string;
}

// エラー:型 'number' を型 'string' に割り当てることはできません
interface Human extends Nameable {
  name:number;
  age: number;
  greeting(msg: string): void;
}


// type
type Nameable = {
  name: string;
};

// 継承できるが、name:neverとなる
type Human = {
  name: number;
  age: number;
  greeting(message: string): void;
} & Nameable;

コンストラクトシグネチャ

// うーん。使いどころがわからない
interface func {
    new (num:number):void;
}

// コンストラクタ専用の型になる
const temp=(cb:func) => {
	const foo = new cb(1);
}

関数型(コールシグネチャ)のインターセクション

// 関数型インターフェースA
interface FuncA {
  (a: number, b: string): number;
  (a: string, b: number): number;
}

// 関数型インターフェースB
interface FuncB {
  (a: number): number;
}

// funcFooの型は↓と同じ(FuncAとFuncBをすべてオーバーロードされている)
// interface xxxx {
//   (a: number, b: string): number;
//   (a: string, b: number): number;
//   (a: number): number;
// }
let funcFoo: FuncA & FuncB;



//funcFooに入れられる関数はFuncAとFuncBで定義している型がすべて入るシグネチャにしなければならない
funcFoo = (a:number|string, b?:string|number) => 0;

keyof

トップレベルのプロパティ名のみユニオン型として返す

// type K = "name" | "age"
type K = keyof { name: { first: string; second: string }; age: number };

Mapped Types

型のfor文

基本
type fruit = {
  [P in "apple" | "banana"]: P;
};

// type fruit = {
//   apple: "apple";
//   banana: "banana";
// }
keyofを使う
interface Fruit {
  apple: string;
  banana: string;
}

type MappedTypes = {
  [P in keyof Fruit]: P;
};

// 元のプロパティの型を使いたい場合はT[P]
type MappedTypes<T> = {
  [P in keyof T]: T[P];
};
エラー:MappedTypesではプロパティやメソッドを追加できない
interface Fruit {
  apple: string;
  banana: string;
}

type MappedFruit = {
  [P in keyof Fruit]: Fruit[P];
  name:string;         // マップされた型ではプロパティやメソッドを宣言できません
};

ジェネリクスを使って汎用的にする

// Fruiteインターフェースを読み取り専用にする
interface Fruit {
  apple: string;
  banana: number;
}

type MappedTypes<T> = {
  readonly [P in keyof T]: T[P];
};

type ReadonlyFruit = MappedTypes<Fruit>;
// type ReadonlyFruit = {
//   readonly apple: string;
//   readonly banana: number;
// }

いろいろカスタム

オプショナルにする
type MappedTypes = {
  [P in "apple" | "banana"]?: string;
};
元のプロパティのreadonlyを消す
interface Fruit {
  readonly apple: string;
  banana: number;
}

type MappedTypes<T> = {
  -readonly [P in keyof T]: T[P];
};

type customFruit = MappedTypes<Fruit>;

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?