1643347200
2012年にMicrosoftによって作成されて以来、TypeScriptは増加しています。プレーンJavaScriptの信頼性を向上させるための目立たないプロジェクトとして始まったTypeScriptは、現在、プロの開発者によって5番目に使用されているプログラミング言語です。TypeScriptがどこにでもあると言っても過言ではありません。
TypeScriptは急速に採用されているため、多くの新しい開発者が毎日TypeScriptの旅に出ています。新しい言語を学ぶことは多くの質問と改善の余地を伴います。昨年のTypeScriptコードを振り返ると、定期的に完全にリファクタリングする必要があると感じています。したがって、Typescriptの旅を始めるため、またはすでに非の打ちどころのない知識を拡大するために、TypeScriptを改善するための5つのあまり知られていないテクニックを紹介します。
オブジェクトと配列の値は、に割り当てられている場合でも、いつでも変更できますconst
。
const array = [1, 2, 3];
array.push(4);
console.log(array);
// 1, 2, 3, 4
const object = {
a: 'value'
};
object.a = 'new value';
console.log(object.a)
// 'new value';
しかし、配列またはオブジェクトの値を変更しないようにしたい場合はどうでしょうか。TypeScriptは、単純なソリューションを提供しas const
ます。宣言の後に値を追加することにより、値とその順序(配列の場合)は不変になります。
const array = [1, 2, 3] as const;
// Property 'push' does not exist on type 'readonly [1, 2, 3]'
array.push(4);
const object = {
a: 'value'
} as const;
// Cannot assign to 'a' because it is a read-only property.
object.a = 'new value';
Enums
スイッチケースに最適です。これらを使用すると、一連の定数に対して値を簡単に確認できます。以下の例では、Fruits
列挙型を使用してケースの果物を見つけ、コンソールに記録します。
enum Fruits {
APPLE = 'apple',
BANANA = 'banana',
};
let pieceOfFruit:Fruits = Fruits.APPLE;
function logFruit(pieceOfFruit: Fruits) {
switch (pieceOfFruit) {
case Fruits.BANANA:
console.log('banana');
break;
case Fruits.APPLE:
console.log('apple');
break;
}
}
しかし、列挙型は拡大する傾向があります。オレンジのような別の種類の果物が好きな場合はどうなりますか?列挙型に追加できますがORANGE
、スイッチケースが変更されていない限り、コンソールに「オレンジ」を記録することはありません。
スイッチが列挙型のすべてのメンバーを占めるようにするために、徹底的なチェックを追加できます。default
ケース内の値をとして入力することによりnever
、この値に到達してはならないことを意味します。したがって、切り替えが不完全で、デフォルト値に達する可能性がある場合は、コンパイルエラーが発生します。
enum Fruits {
APPLE = 'apple',
BANANA = 'banana',
ORANGE = 'orange',
};
let pieceOfFruit:Fruits = Fruits.ORANGE;
function logFruit(pieceOfFruit: Fruits) {
switch (pieceOfFruit) {
case Fruits.BANANA:
console.log('banana');
break;
case Fruits.APPLE:
console.log('apple');
break;
default:
//Type 'Fruits' is not assignable to type 'never'
const defaultFruit: never = pieceOfFruit;
}
}
unknown’
上記」を選択しますany’
any
TypeScriptの場合は、衣類の「1つのサイズですべてに対応」のようなものです。あらゆる状況に適用できますが、フィット感が悪く、お世辞もほとんどありません。の問題any
は、タイプセーフではないことです。つまり、タイプエラーが発生する可能性があります。
たとえば、数値を含むa
型の変数があるとします。any
型安全性がないため、この番号を文字列として型指定された変数に割り当てるか、関数と呼ぶことができます。これは明らかに問題を引き起こします。
unknown
のタイプセーフな対応物ですany
。つまり、unknownには任意の値を割り当てることができますが、 unknownをどの値にも割り当てることはできません。したがって、使用any
するとTypeScriptの目的が完全に失われますが、unknown
型の安全性を犠牲にすることなく、不明確な型を操作できます。
// ANY
const a: any = 10;
// valid: any can be assigned to everthing;
const b: string = a;
// valid: any may be a function
a();
// UNKNOWN
const c: unknown = 10;
// invalid: Type 'unknown' is not assignable to type 'string'.
const d: string = c;
// invalid: Object is of type 'unknown'.
c();
// CAST UNKNOWN
const e: unknown = 'string';
// cast unkown as string
const f: string = e as string;
JavaScriptを使用するということは、オブジェクトを操作することを意味します。実際、それは多くのオブジェクトを操作することを意味します。このため、JS関数は、さまざまな種類のオブジェクトから動的に値を取得するために、オブジェクトのキーをパラメーターとして受け入れることがよくあります。
しかし、与えられたキーが存在することをどのように保証しますか?Date
キーを使用して値を取得しようとしたcreatedAt
が、キーの名前がであるとしcreated
ます。これらの種類のエラーは、厄介なバグや予期しない動作につながる可能性があります。
generic
タイプと属性の力を利用することによりkeyof
、提供されたキー名が存在することを確認できます。dateKey
以下の例では、2番目のパラメーターを指定されたタイプの有効なキーに制限し、存在しないキーのリスクを排除します。
interface Car {
constructedAt: Date;
brand: string;
}
interface Bycicle {
soldAt: Date;
brand: string;
}
function getDate<T>(item: T, dateKey: keyof T) {
return item[dateKey];
}
const car: Car = {
constructedAt: new Date(),
brand: 'BMW'
};
const bycicle: Bycicle = {
soldAt: new Date(),
brand: 'Canyon',
};
// Argument of type '"soldAt"' is not assignable to parameter of type 'keyof Car'
getDate<Car>(car, 'soldAt');
// valid
getDate<Car>(car, 'constructedAt');
// Argument of type '"constructedAt"' is not assignable to parameter of type 'keyof Bycicle'
getDate<Bycicle>(bycicle, 'constructedAt');
// Valid
getDate<Bycicle>(bycicle, 'soldAt');
キーと値のペアの正確なタイプが事前にわからない場合があります。情報が不足しているため、これによりインターフェイスの作成が複雑になります。このような場合、TypeScriptRecord
が役に立ちます。
Record
許可キーと値のタイプを提供することにより、タイプを定義できます。したがって、たとえば、Record<string, number>
文字列型のキーと数値型の値を持つオブジェクトに対応します。
type A = Record<string, number | string[]>;
// INVALID
const a: A = {
// Type '() => null' is not assignable to type 'number | string[]'.
a: () => null,
// Type 'number' is not assignable to type 'string'.
b: [1],
};
// VALID
const b: A = {
a: 200,
b: ['a', 'b', 'c']
}
これで完了です。途中で何かを学んだことを願っています。記事が気に入りましたか?それなら、以下の私の記事でも役立つものを見つけて楽しんでいただけると思います。
1643347200
2012年にMicrosoftによって作成されて以来、TypeScriptは増加しています。プレーンJavaScriptの信頼性を向上させるための目立たないプロジェクトとして始まったTypeScriptは、現在、プロの開発者によって5番目に使用されているプログラミング言語です。TypeScriptがどこにでもあると言っても過言ではありません。
TypeScriptは急速に採用されているため、多くの新しい開発者が毎日TypeScriptの旅に出ています。新しい言語を学ぶことは多くの質問と改善の余地を伴います。昨年のTypeScriptコードを振り返ると、定期的に完全にリファクタリングする必要があると感じています。したがって、Typescriptの旅を始めるため、またはすでに非の打ちどころのない知識を拡大するために、TypeScriptを改善するための5つのあまり知られていないテクニックを紹介します。
オブジェクトと配列の値は、に割り当てられている場合でも、いつでも変更できますconst
。
const array = [1, 2, 3];
array.push(4);
console.log(array);
// 1, 2, 3, 4
const object = {
a: 'value'
};
object.a = 'new value';
console.log(object.a)
// 'new value';
しかし、配列またはオブジェクトの値を変更しないようにしたい場合はどうでしょうか。TypeScriptは、単純なソリューションを提供しas const
ます。宣言の後に値を追加することにより、値とその順序(配列の場合)は不変になります。
const array = [1, 2, 3] as const;
// Property 'push' does not exist on type 'readonly [1, 2, 3]'
array.push(4);
const object = {
a: 'value'
} as const;
// Cannot assign to 'a' because it is a read-only property.
object.a = 'new value';
Enums
スイッチケースに最適です。これらを使用すると、一連の定数に対して値を簡単に確認できます。以下の例では、Fruits
列挙型を使用してケースの果物を見つけ、コンソールに記録します。
enum Fruits {
APPLE = 'apple',
BANANA = 'banana',
};
let pieceOfFruit:Fruits = Fruits.APPLE;
function logFruit(pieceOfFruit: Fruits) {
switch (pieceOfFruit) {
case Fruits.BANANA:
console.log('banana');
break;
case Fruits.APPLE:
console.log('apple');
break;
}
}
しかし、列挙型は拡大する傾向があります。オレンジのような別の種類の果物が好きな場合はどうなりますか?列挙型に追加できますがORANGE
、スイッチケースが変更されていない限り、コンソールに「オレンジ」を記録することはありません。
スイッチが列挙型のすべてのメンバーを占めるようにするために、徹底的なチェックを追加できます。default
ケース内の値をとして入力することによりnever
、この値に到達してはならないことを意味します。したがって、切り替えが不完全で、デフォルト値に達する可能性がある場合は、コンパイルエラーが発生します。
enum Fruits {
APPLE = 'apple',
BANANA = 'banana',
ORANGE = 'orange',
};
let pieceOfFruit:Fruits = Fruits.ORANGE;
function logFruit(pieceOfFruit: Fruits) {
switch (pieceOfFruit) {
case Fruits.BANANA:
console.log('banana');
break;
case Fruits.APPLE:
console.log('apple');
break;
default:
//Type 'Fruits' is not assignable to type 'never'
const defaultFruit: never = pieceOfFruit;
}
}
unknown’
上記」を選択しますany’
any
TypeScriptの場合は、衣類の「1つのサイズですべてに対応」のようなものです。あらゆる状況に適用できますが、フィット感が悪く、お世辞もほとんどありません。の問題any
は、タイプセーフではないことです。つまり、タイプエラーが発生する可能性があります。
たとえば、数値を含むa
型の変数があるとします。any
型安全性がないため、この番号を文字列として型指定された変数に割り当てるか、関数と呼ぶことができます。これは明らかに問題を引き起こします。
unknown
のタイプセーフな対応物ですany
。つまり、unknownには任意の値を割り当てることができますが、 unknownをどの値にも割り当てることはできません。したがって、使用any
するとTypeScriptの目的が完全に失われますが、unknown
型の安全性を犠牲にすることなく、不明確な型を操作できます。
// ANY
const a: any = 10;
// valid: any can be assigned to everthing;
const b: string = a;
// valid: any may be a function
a();
// UNKNOWN
const c: unknown = 10;
// invalid: Type 'unknown' is not assignable to type 'string'.
const d: string = c;
// invalid: Object is of type 'unknown'.
c();
// CAST UNKNOWN
const e: unknown = 'string';
// cast unkown as string
const f: string = e as string;
JavaScriptを使用するということは、オブジェクトを操作することを意味します。実際、それは多くのオブジェクトを操作することを意味します。このため、JS関数は、さまざまな種類のオブジェクトから動的に値を取得するために、オブジェクトのキーをパラメーターとして受け入れることがよくあります。
しかし、与えられたキーが存在することをどのように保証しますか?Date
キーを使用して値を取得しようとしたcreatedAt
が、キーの名前がであるとしcreated
ます。これらの種類のエラーは、厄介なバグや予期しない動作につながる可能性があります。
generic
タイプと属性の力を利用することによりkeyof
、提供されたキー名が存在することを確認できます。dateKey
以下の例では、2番目のパラメーターを指定されたタイプの有効なキーに制限し、存在しないキーのリスクを排除します。
interface Car {
constructedAt: Date;
brand: string;
}
interface Bycicle {
soldAt: Date;
brand: string;
}
function getDate<T>(item: T, dateKey: keyof T) {
return item[dateKey];
}
const car: Car = {
constructedAt: new Date(),
brand: 'BMW'
};
const bycicle: Bycicle = {
soldAt: new Date(),
brand: 'Canyon',
};
// Argument of type '"soldAt"' is not assignable to parameter of type 'keyof Car'
getDate<Car>(car, 'soldAt');
// valid
getDate<Car>(car, 'constructedAt');
// Argument of type '"constructedAt"' is not assignable to parameter of type 'keyof Bycicle'
getDate<Bycicle>(bycicle, 'constructedAt');
// Valid
getDate<Bycicle>(bycicle, 'soldAt');
キーと値のペアの正確なタイプが事前にわからない場合があります。情報が不足しているため、これによりインターフェイスの作成が複雑になります。このような場合、TypeScriptRecord
が役に立ちます。
Record
許可キーと値のタイプを提供することにより、タイプを定義できます。したがって、たとえば、Record<string, number>
文字列型のキーと数値型の値を持つオブジェクトに対応します。
type A = Record<string, number | string[]>;
// INVALID
const a: A = {
// Type '() => null' is not assignable to type 'number | string[]'.
a: () => null,
// Type 'number' is not assignable to type 'string'.
b: [1],
};
// VALID
const b: A = {
a: 200,
b: ['a', 'b', 'c']
}
これで完了です。途中で何かを学んだことを願っています。記事が気に入りましたか?それなら、以下の私の記事でも役立つものを見つけて楽しんでいただけると思います。