0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TypeScriptの型まとめ(2024年10月) - ちょっとだけkintone

Last updated at Posted at 2024-10-17

JSDocでも使うので、型が書けないと実践的なJavaScriptも書けないと思います。
でもめちゃくちゃめんどくさいですよね。

TypeScriptを書き始めのころはなんでもかんでも型を書いちゃうし、型が分からなくてanyにしちゃったりしますよね。

ここではできるだけ型を書かなくてもよくする方法をまとめます。

基本

type TypeA = {
    type: "a";
    name: "hoge" | "bar";
    value: string;
}
type TypeB = {
    type: "b";
    id: "hoge" | "bar";
    value: 0;
}

//複合的な型(TypeAかTypeBのどちらか)
type ConbinedType = TypeA | TypeB;

//結合された型(TypeAであり同時にTypeBである)
type ConnectedType = TypeA & TypeB;
/* 型推論 */

type Example = {
    a: string;
    b: string;
}

//プロパティの型を取得する。
type ExampleType = Example['a'];

const array : Example[] = [{
    a: 'a',
    b: 'b',
} , {
    a: 'A',
    b: 'B',
}];

///すごく長いコード......///

//arrayのメンバーの型定義がソースコード上深すぎてわからないとき、型推論から型を取り出す。
type ArrayMemberType = typeof array[0];
/* クラスの型 */
class Processor {
    process(){
        return 'done';
    }
}

//クラスの型を取得する
type ProcessorType = typeof Processor;

//クラスのメソッドの型を取得する
type ProcessFunctionType = ProcessorType['prototype']['process'];

const instance = new Processor();

//インスタンス化されているクラス内の関数の型を取得する。
type InstanceProcessFunctionType = typeof instance.process;

戻り値(ReturnType)

//例えば初期値を定義する関数があるとする。
function createInit(){
    const initData : {
        id : string;
        name : string;
    } = {
        id : "hoge",
        name : "fuga"
    }

    return initData;
}

//関数の構造を型として定義する
export type CreaterType = typeof createInit;

//関数の戻り値の型をデータ型として定義して使う
export type AppState = ReturnType<CreaterType>;

非同期処理(Awaited)


//文字列や数値が非同期に帰ってくる関数。
async function asyncRandom() {
    if (Math.random() > 0.5) {
        return 'done';
    }else{
        return 0;
    }
}

//() => Promise<string>
type AsyncType = typeof asyncRandom;

//戻り値を表現する型
type AsyncReturnType = Awaited<ReturnType<AsyncType>>;
// -> "done" | 0

複数の型を処理できるようにする

type TypeA = {
    //型を複合して使う場合、分類用のプロパティを用意しておく
    type : "a";
    name : "hoge" | "bar";
    value : string;
}
type TypeB = {
    //型を複合して使う場合、分類用のプロパティを用意しておく
    type : "b";
    id : "hoge" | "bar";
    value : 0;
}

//テストデータ
const data : (TypeA | TypeB)[] = [{
    type : "a",
    name : "hoge",
    value : "fuga"
}, {
    type : "b",
    id : "hoge",
    value : 0
}];

for(let datum of data){
    //複合的な型から、型推論を利用して型を矯正する
    if("a" == datum.type){
        //nameはTypeAのプロパティなので、TypeBには存在しない
        console.log(datum.name);
    }else{
        //idはTypeBのプロパティなので、TypeAには存在しない
        console.log(datum.id);
    }
}

プロパティの算法(Partial, Pick, Omit)


type ManyProperty = {
    a : string;
    b : string;
    c : string;
    d : string;
    e : string;
}

//"a"しかプロパティがない型
type OnlyA = Pick<ManyProperty, 'a'>;
/* ->
type OnlyA = {
    a: string;
}
*/

//すべてのプロパティが必須ではないかもしれない型
type PatialManyProperty = Partial<ManyProperty>;
/* ->
type PatialManyPropertye = {
    a?: string | undefined;
    b?: string | undefined;
    c?: string | undefined;
    d?: string | undefined;
    e?: string | undefined;
}
*/

//すべてのプロパティが必須になった型
type RequiredManyProperty = Required<PatialManyProperty>;
/* ->
type RequiredManyProperty = {
    a: string;
    b: string;
    c: string;
    d: string;
    e: string;
}
*/

//"a"と"b"をプロパティに含まない型
type NotInclueAB = Omit<ManyProperty, 'a' | 'b'>;
/* ->
type NotInclueAB = {
    c: string;
    d: string;
    e: string;
}
*

KintoneRestAPIClientを利用するときの型推論

インポートする。

npm i @kintone/rest-api-client
import type { KintoneRestAPIClient } from '@kintone/rest-api-client';

//getFormFieldsの戻り値の型を取得する。
type FormResponse = Awaited<ReturnType<typeof KintoneRestAPIClient['prototype']['app']['getFormFields']>>;
/*
type FormResponse = {
    properties: Properties;
    revision: string;
}
*/

//レコード取得したときの型(あんまり意味ないけど)
type RecordResponse = Awaited<ReturnType<typeof KintoneRestAPIClient['prototype']['record']['getAllRecords']>>;

//kintoneのフォームに定義できる型(typeプロパティ)の一覧
type FieldType = FormResponse['properties'][string]['type'];

👇FieldTypeをVSCodeで覗いたところ。
image.png

このように、stringではなく、明示的な定数で定義されるので、switch文などの展開で安全にコーディングをすすめられます。

まとめ

TypeScriptでは型演算と型推論を利用し、処理を書いている間はほぼ型定義なしで書き進められます。

型を利用できるようになると、開発環境のインテリセンス(サジェストを表示する機能)を利用して安全で高速に開発ができます。体感で倍以上は開発速度が違うと思います。

みなさまも、よく使うやり方があったら教えてください!


この記事は以上です。ありがとうございました。

kintoneのプラグイン開発や研修などを行っています。
お仕事のお話はこちらまで。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?