はじめに
この記事は「プロを目指す人のためのTypeScript入門」を元にアウトプットした記事になります。
また私の現在のレベルは実務経験1年程度の駆け出しフロントエンドエンジニアなので、もし誤った解釈などしておりましたらコメントでご指摘いただけますと幸いです。
対象者
この記事は下記のような人を対象にしています。
- TypeScript学習中の方
- Vue.jsやReactの知見はある程度あるが、TypeScriptの知見が乏しい方
(↑まさに自分はこれでした。。。)
それでは早速アウトプットに入っていきます。
(序盤はJavaScriptに関するアウトプットが多いです。)
内容
constでもプロパティの再代入は可能
cosnt obj = {
foo: 123,
bar: 'aaa',
}
// ok
obj.foo = 456
// no
cosnt obj = {
foo: 456,
bar: 'bbb',
}
定数宣言の「const」を使っていてもプロパティの値は変更できます。
当然ですが、再宣言はNG
また、最近はプロパティの最後にも「,」を付けるのが慣例らしいです。
理由は下の2つです。
①「要素」の間に「,」が並んでいるという見方から「要素,」のセットが並んでいるというシンプルな見方に変えることができる
②Gitでも余分な差分を発生させずに済む。
オブジェクトの比較は値ではなくメモリで見る。
const foo = { num: 1234 };
const bar = foo;
const baz = { num: 1234 };
// true
console.log(foo === bar);
// false
console.log(foo === baz);
const bar = foo
は同じメモリの値を変数barと変数fooの2箇所に格納している状態です。
そのため比較をしてもtrueとなります。
しかし、新しいメモリを使って生成した変数bazについては、たとえ中身が全く同じだったとしてもメモリ自体は別々なのでflaseとなります。
*自分の別記事ですがこちらを見るとよく分かるかもしれません。
【JavaScript】使用してはまずい破壊的メソッドの話
TypeScriptでは2つの方宣言がある。
// type文
// TypeScriptではかなり頻出
// オブジェクト型以外もなんでもok
type FooBarObj = {
foo: 123,
bar: 'test',
}
// interface宣言(ほぼ使わない)
// 2014年以前使われていたらしい
// interface宣言が使えるのはオブジェクト型のみ
interface FooBarObj {
foo: 123;
bar: 'test';
}
TypeScriptの型宣言には以下の2つがあります。
①type文での型宣言
②interface宣言
ただし今は①メインで使われており、②は2014年以前に使われていたものらしいです。
利便性もtype文ではプリミティブ型やオブジェクト型関係なく、何でも型宣言できるのに対し、interface宣言ではオブジェクト型のみなので、type文のみ抑えとけば問題なさそうです。
動的プロパティの時に用いるインデックスシグネチャ
type PriceData = {
[key: string]: number;
}
const data: PriceData = {
apple: 220,
coffee: 120,
bento: 500,
}
// ok
data.chicken = 250;
// コンパイルエラー
// Type '"foo"' is not assignable to type 'number'.
data.弁当 = "foo";
プロパティ名が動的に決まるときはtype文での型宣言ではなく、インデックスシグネチャを使います。
[key: string]とは、「任意のstring型のキーに対して」という意味。
オブジェクトのプロパティ名は全て文字列で表現されるので、これは「任意のプロパティ名に対して」とも言い換えることが可能。
ただし、このインデックスシグネチャはあまり多用すべきではないっぽいです。
理由は、TypeScriptが保証する方安全機能を破壊してしまうからです。
オプショナルなプロパティの宣言
type MyObj = {
foo: boolean;
bar: boolean;
baz?: number;
}
const obj: MyObj = { foo: false, bar: true };
const obj2: MyObj = { foo: true, bar: false, baz: 1234 };
オプショナルなプロパティとはあってもなくてもよいプロパティのことを指します。
(上記コードのbaz?: number;
がそうです。)
これがあることでエラーにならず、プロパティアクセスを行えます。
console.log(obj.baz); // undefined
console.log(obj2.baz); // 1234
またVScodeでobj.bazにマウスカーソルを乗せると、number | undefined
型と表示されます。
これはユニオン型とも言われ、「number型かもしれないし、undefined型かもしれない」という意味です。
さらにこの状態だと通常のnumber型のように扱うことができません。
console.log(obj2.baz * 1000); // コンパイルエラー
// ok
if(obj2.baz !== undefined) {
console.log(obj2.baz * 1000);
}
読み取り専用プロパティの宣言
type MyObj = {
readonly foo: number;
}
const obj: MyObj = { foo: 123 };
// エラー: Cannot assign to 'foo' because it is a read-only peoperty.
obj.foo = 0;
readonly
を付けることで読み取り専用となります。
再代入しようとするとコンパイルエラーが起きます。
特にプロパティを変更する予定が無ければreadonlyをつけておく方が安全です。
最後に
「プロを目指す人のためのTypeScript入門」を参考にアウトプットしてますが非常に分かりやすくおすすめです。
一旦は以上ですが、また時間ある時に続きのアウトプットを書きたいと思います。
もし何かあればコメントしていただけると助かります!