TypeScriptを極めよう!
TypeScriptは次世代のVBAになるほどMicrosoftがプッシュしています。
TypeScriptからファイルシステムにアクセスすることはできませんが
PowerAutomateと一緒に使うことで高度な処理が実現できます。
それではいきましょう!
1. 型推論の高度な使用法
TypeScriptの型推論は非常に強力です。複雑な型推論の例を見てみましょう。
function createPair<T, U>(v1: T, v2: U): [T, U] {
return [v1, v2];
}
let pair = createPair("hello", 42);
// pairの型は [string, number] と推論されます
2. 条件付き型の応用
条件付き型を使用して、入力に基づいて型を動的に選択できます。
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
type T0 = TypeName<string>; // "string"
type T1 = TypeName<"a">; // "string"
type T2 = TypeName<true>; // "boolean"
type T3 = TypeName<() => void>; // "function"
type T4 = TypeName<string[]>; // "object"
3. マップ型と高度な型変換
マップ型を使用して、既存の型から新しい型を作成できます。
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type Partial<T> = {
[P in keyof T]?: T[P];
};
interface Person {
name: string;
age: number;
}
type ReadonlyPerson = Readonly<Person>;
// { readonly name: string; readonly age: number; }
type PartialPerson = Partial<Person>;
// { name?: string; age?: number; }
4. 高度なジェネリック制約
ジェネリック型に複雑な制約を適用できます。
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // プロパティ 'length' は存在します
return arg;
}
loggingIdentity(3); // エラー、numberには 'length' プロパティがありません
loggingIdentity({length: 10, value: 3}); // OK
5. 型の交差と合成
型の交差を使用して、複数の型を組み合わせることができます。
interface ErrorHandling {
success: boolean;
error?: { message: string };
}
interface ArtworksData {
artworks: { title: string }[];
}
type ArtworksResponse = ArtworksData & ErrorHandling;
let response: ArtworksResponse = {
artworks: [{ title: "Mona Lisa" }],
success: true
};
6. 高度なインデックス型
インデックス型を使用して、オブジェクトのプロパティを動的に参照できます。
function pluck<T, K extends keyof T>(o: T, propertyNames: K[]): T[K][] {
return propertyNames.map(n => o[n]);
}
interface Car {
manufacturer: string;
model: string;
year: number;
}
let taxi: Car = {
manufacturer: 'Toyota',
model: 'Camry',
year: 2014
};
let makeAndModel = pluck(taxi, ['manufacturer', 'model']);
// makeAndModelの型は (string | number)[]
7. 型ガードとアサーション関数
カスタム型ガードを作成して、より精密な型チェックを行うことができます。
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(): void;
layEggs(): void;
}
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
function move(pet: Fish | Bird) {
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
}
}
8. 再帰型
再帰型を使用して、ネストされたデータ構造を表現できます。
type JSONValue =
| string
| number
| boolean
| null
| JSONValue[]
| { [key: string]: JSONValue };
const data: JSONValue = {
name: "John",
age: 30,
isStudent: false,
hobbies: ["reading", "swimming"],
address: {
street: "123 Main St",
city: "Anytown"
}
};
9. テンプレートリテラル型の高度な使用法
テンプレートリテラル型を使用して、文字列ベースの複雑な型を作成できます。
type EmailLocaleIDs = "welcome_email" | "email_heading";
type FooterLocaleIDs = "footer_title" | "footer_sendoff";
type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`;
// "welcome_email_id" | "email_heading_id" | "footer_title_id" | "footer_sendoff_id"
type Lang = "en" | "ja" | "pt";
type LocaleMessageIDs = `${Lang}_${AllLocaleIDs}`;
// "en_welcome_email_id" | "en_email_heading_id" | "en_footer_title_id" | "en_footer_sendoff_id" |
// "ja_welcome_email_id" | "ja_email_heading_id" | "ja_footer_title_id" | "ja_footer_sendoff_id" |
// "pt_welcome_email_id" | "pt_email_heading_id" | "pt_footer_title_id" | "pt_footer_sendoff_id"
10. 高度な型レベルプログラミング
TypeScriptの型システムを使用して、複雑な計算を型レベルで実行できます。
type Subtract<T extends number, U extends number> =
[...Array<T>]['length'] extends [...Array<U>, ...infer Rest]
? Rest['length']
: never;
type Result = Subtract<5, 3>; // 2
type Fibonacci<N extends number, A extends number[] = [1], B extends number[] = [1]> =
N extends 0 ? 0 :
N extends 1 ? 1 :
N extends 2 ? 1 :
A['length'] extends N ? B['length'] :
Fibonacci<N, B, [...A, ...B]>;
type Fib5 = Fibonacci<5>; // 5
type Fib10 = Fibonacci<10>; // 55
これらの高度な型システムの機能を理解し活用することで、より堅牢で表現力豊かなTypeScriptコードを書くことができます。型システムを深く理解することは、バグの早期発見やコードの自己文書化につながり、大規模なアプリケーション開発において非常に有益です。