はじめに
普段はvue・Typescriptで主に開発しているのですが、Typescriptで提供されている
utilityTypes をあまり使わずに開発していることが多かったので使用していきたいと思い、使えそうなやつをピックアップして紹介します!
Pick< T, K >
既に用意されているTypeから必要な項目だけを抜き出した新しい型を作りたい時に使用する`
type Person = {
name: string;
age: number;
email: string;
address: string;
}
type PickedPerson = Pick<Person, 'name' | 'age'>
// => type Student = {name: string, age: number}と同義
const taro: PickedPerson = {
name: 'Taro',
age: 10,
}
Partial< T >
存在する型の全てをOptionalのプロパティに変換する
type Person {
name: string;
age: number;
email: string;
address: string;
}
type PartialPerson = Partial<Person>
// Person型の全てのプロパティをOptionalに変換
const taro: PartialPerson = {
name: 'Taro',
}
// => age, email, addressがなくてもエラーにならない
Required< T >
全てのプロパティを必須のプロパティに変換する
type Person {
name?: string;
age?: number;
email?: string;
address?: string;
}
type RequiredPerson = Required<Person>
// Person型の全てのプロパティを必須プロパティに変換
const taro: RequiredPerson = {
name: 'Taro',
}
// エラー => age, email, addressがないのでエラー
Omit< T, K >
既に存在する型の中から選択した一部のプロパティを除いて新たな型を作成する。
Pickの逆ですね。
type Person = {
name: string;
age: number;
email: string;
address: string;
}
type OmittedPerson = Omit<Person, 'name'>
// => Personから'name'を除いた型を作成
const taro: OmittedPerson = {
age: 10,
email: 'test@example.com'
address: 'test5-57-5'
}
Record< Keys, Type >
プロパティのキーがKeysであり、プロパティの値がTypeであるオブジェクト型を作る
type Person = Record<"firstName" | "middleName" | "lastName", string>;
const person: Person = {
firstName: "花子",
middleName: "duran",
lastName: "田中",
};
もっと踏み込むと以下の様な使い方ができます。
type Animal = {
name: string;
age: number;
}
type List = {
lion:Animal;
dog:Animal;
cat:Animal;
}
const list:List = {
lion: { name:'lion',age:4 },
dog: { name:'dog',age:15 },
cat: { name:'saburo',age:18 },
}
List
型のキーは全てAnimal
である。ここをなんとかしたい。
Record
を使い以下の様にする。
type Animal = {
name: string;
age: number;
}
type List = 'lion' | 'dog' | 'cat';
// Listのユニオンタイプ('lion' | 'dog' | 'cat')がキー、 Animalが値の型を作成する
const list:Record<List,Animal>= {
lion: { name:'lion',age:4 },
dog: { name:'dog',age:15 },
cat: { name:'saburo',age:18 },
}
ReturnType< T >
関数の戻り値の型から新たな型を生成します
type StringType = ReturnType<() => string>; // 返り値がstringの関数
// type StringType = string
type ObjectType = ReturnType<(value: string) => { name: string; old: number }>; // 返り値がオブジェクトの関数
// type ObjectType = { name: string; old: number; }
const callStudent = (student: string, teacher: string): void => {
console.log(`${teacher}: 元気ですか? ${student}: はい元気です!`);
};
type CallType = ReturnType<typeof callStudent>; // 返り値がvoidの関数
// type CallType = void
番外編
Conditional Types
型定義の際に三項演算子を使える
type IsString<T> = T extends string ? true : false
// Tの型がstringかどうかで判定される
type A = IsString<'a'> // type A = true
type B = IsString<1> // type B = false
type C = IsString<boolean> // type C = false
Conditonal Types
はnever
型と組み合わせることが多いので、never型の特性について紹介すると
never型にはどんな値もセットできない型なので、T | never
というUnion型はT
になります。
つまり、never型
は排除されるということです。
以下never型を条件に入れてConditional Typesを利用した例です。
type Student = {
name: string;
grade: number;
}
type Teacher = {
name: string;
age: number;
role: string;
}
type Animal = {
name: string;
age: number;
}
type SelectedPerson = Student | Teacher;
// SelectedPersonを満たす型のみをフィリタリングする。
// falseの時はnever型つまり排除される
type SelectedPersonFilter<T> = T extends SelectedPerson ? T : never;
// Animalは SelectedPersonを満たさないので SelectedPersonTypeから除外されている
type SelectedPersonType = SelectedPersonFilter<Student | Teacher | Animal>
// type SelectedPersonType = Student | Teacher
最後に
utility typesはせっかく用意してくれているのに使用していないことが多かったので
今後は使用していこうかなと思いました。
誰かの参考になれば幸いです。