交差型
交差型とは複数の型を合せた新しい型定義
type Admin = {
name: string,
privileges: string[],
};
type Employee = {
name: string,
startDate: Date,
};
type ElevatedEmployee = Admin & Employee;
このように記述すると
type ElevatedEmployee = {
name: string,
privileges: string[],
startDate: Date,
}
という型定義になる。重複しているnameについては特に何も起こらない。
DateはJavaScriptの存在するDateオブジェクトの型であることを定義している。
なおinterfaceを使っても同様の定義をすることができる。
interface Admin {
name: string;
privileges: string[];
}
interface Employee {
name: string;
startDate:Date;
}
interface ElevatedEmployee extends Admin,Employee {}
ちょっと長くなる。
型ガード
型の定義とは別に処理内で型の検査を行う。
type Combinable = string | nubmer;
type Numeric = number | boolean;
function add(a: Combinable, b: Combinable) {
if (typeof a === 'string' || typeof b === 'string') {
return a.toString() + b.toString();
}
return a + b;
}
このようにするとどちらかが文字列の場合は文字列として連結、違う場合(どちらも数値)足し算を行う関数になる。
これは関数内でtypeofによる型ガードを行っているため。
type UnknownEmployee = Employee | Admin;
function printEmployeeInfomation(emp: UnknownEmployee) {
colose.log(emp.name);
if ('privileges' in emp) {
console.log(emp.privileges);
}
if ('startDate' in emp) {
console.log(emp.startDate);
}
}
printEmployeeInformation({name: 'taku', startDate:new Date()});
inはJavaScriptに存在する演算子で指定したプロパティが指定したオブジェクトの中に存在するか探すもの。(あった場合trueを返す。)
このempというオブジェクトは存在しないが、これはエイリアスでありたどると
type Admin = {
name: string;
privileges: string[];
};
type Employee = {
name: string;
startDate: Date;
};
このオブジェクトであることが分かる。
また、このinによる型ガードはinterfaceで定義している場合使う事が出来ない。
なぜなら、interfaceはTypeScript上にしか存在しないため、コンパイルされた時にオブジェクトの定義として残らない為エラーになってしまうからである。
今回躓いたのはmicroCMSでのブログ作成時の型定義について。
sdkを用いてAPIにアクセスする際に組み込み関数のcreateClientを使用するのだがTypeScriptで使用するとエラーが発生していた。
export const client = createClient({
serviceDomain: 'xxxxxxxxx',
apiKey: process.env.API_KEY , //ここがエラー
});
どうやら同じく組み込まれたClientParamsという型定義に問題があるよう。覗いてみると
export interface ClientParams {
serviceDomain: string;
apiKey: string;
globalDraftKey?: string;
}
このように定義されていてどうやらapiKeyはstringしか受け付けないよう。
現状ではundefindが渡ってくる可能性があるためエラーが発生していた。
考えられる方法としてオプショナルチェイニングを使用すればよいのだが、組み込みされたものなので良くない気が・・・
apikey?: string; //こうすればundefindである可能性も定義できる
そこでいいものを見つけた。??を使えばよいとのこと。
export const client = createClient({
serviceDomain: 'xxxxxxxxxxx',
apiKey: process.env.API_KEY ?? '',
});
この記述により左辺がnull / undefindだった場合右辺を返すという意味になり、確実にstringが渡ってくることが明示できエラーが解消できる。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator