「TypeScriptの型入門」で手を動かす - その9
本日は「TypeScriptの型入門」の「オブジェクト型再訪」と「asによるダウンキャスト」で手を動かします!
オブジェクト型再訪
- プロパティに対して修飾子をつけられる
?
とreadonly
?
- 省略可能を示す
- ?がついたプロパティの型は
指定した型 | undefined
となる。- 任意プロパティで取得できないことがあるため
undefined
とのunion型のほうがおすすめらしい
- ?をつけずに
型 | undefined
と指定した場合はプロパティ自体は存在してないと行けない- ?よりこっちの方がおすすめらしい
- ?はプロパティが無い場合に、本当に無いのか書き忘れなのかの区別ができない
- 後者(undefinedとのunion型)は書き忘れを防ぐことができる
- ?が必要なパターンとは?
- 本当に無くても良いオブジェクトを渡すのは、関数にオプションオブジェクトを渡すときくらい
- なるほど。
- 本当に無くても良いオブジェクトを渡すのは、関数にオプションオブジェクトを渡すときくらい
exactOptionalPropertyTypes
- オプショナルなプロパティの挙動の定義
- デフォルトは無効
- TypeScript4.4で追加
- 無効なとき
bar?: number
はbar?: number | undefined
とナオジ- barにundefinedを明示的に入れることができる
- オプションがONなら、undefinedはありえないので、プロパティが存在するか、値が入っているかの2択になる
in
演算子を用いて絞り込みができる
readonly
- 再代入できなくする
- constのプロパティ版と考えてよい
- 素のJavaScriptでもObjectプロパティ定義で、writable属性があるが、型システムに組み込むのは筋が悪いらしく、独自の方法を取っているらしい
- ただし、readonlyではない型を経由して書き換えることができるので、過信してはいけない
インデックスシグネチャ
[key: string]: number
の部分。任意のstring型のプロパティ名に対して、number型を持つという定義- undefinedになるプロパティを参照しても、コンパイルエラーにならない。
- 危険
- インデックスシグネチャはオブジェクトを辞書の用に使うときに使える仕組み
- でも、Mapがあるので、Mapを使った方がよい
interface MyObj { [key: string]: number }
関数シグネチャ
- オブジェクト型の記法で関数型を表現する方法がある
- 以下の
(arg: number):void
部分- 本来は
f : (arg:number) => void
みていな関数型をプロパティに付与するのが普通だと思う。
- 本来は
- ちょっと使い所はわからなかったが、関数にプロパティを付与した型を定義できる
interface Foo { (arg: number): void; } const f: Func = (arg: number) => { console.log(arg) }
newシグネチャ
- コンスタントであることを表すシグネチャ
new():T
の部分
interface Ctor<T> { new() : T }
asによるダウンキャスト
式 as 型
と書く- ダウンキャストとは派生型の値を部分型として扱う
string | number
型をnumber
型として扱うas
を使っても全く関係ない2つの値を変換できないstring
型の値をas number
でnumber型に代入なんてことはできない- できなかったんか。
any
型かunknown
型を経由すれば変換できる
as
はアップキャストもできる- 部分型を派生型として扱うってことかな。
as
を使わなくてもアップキャストはできるので、アップキャストでas
を使うのはやめたほうがよい。- 危険なダウンキャストとの見分けがつかなくなるから
- リテラル型をプリミティブ型に代入とかもアップキャストか
1
型をnumber型に代入
本日はここまで、次は「readonlyな配列とタプル」で手を動かします!