「型指定の方法」と「基本型の種類」

TypeScriptの「型指定の方法」と「基本型の種類」について解説します。型指定することで、どういった制約が掛けられるのか確認していきます。

型指定の影響

JavaScriptTypeScript には以下の違いがあります。

  • JavaScript
    • 動的型付け
    • 弱い型付け(他の型の代入も許可する)
  • TypeScript
    • 静的型付け
    • 強い型付け(他の型の代入を許可しない)

具体的に確認します。以下のようなコードがあります。

let xxx = 'hello'
xxx = 33

console.log(xxx)

xxx には 文字列(string) を格納して、その後に 数値(number) を格納しています。

JavaScriptは弱い型付けのため、問題なく実行できます。そのため、意図しない型の値が格納されて不具合が生まれる可能性が高まります。

TypeScriptであれば、以下のようにコンパイルエラーとなります。

$ tsc test1.ts
test1.ts:2:1 - error TS2322: Type '33' is not assignable to type 'string'.

2 xxx = 33
  ~~~


Found 1 error.

TypeScriptは、強い型付けのため、xxxstring 以外の値を代入しようとしたらエラーとなります。厳格に型の管理をすることで、意図しない不具合を防ぐことができます。

型指定の方法

以下のように、関数の引数 関数の戻り値 変数: 型 の形式で明示的に型指定することができます。

const twice = (count: number): string => {
    return `2倍にすると ${count * 2} です。`
}

let myCount: number
myCount = 100

console.log(twice(myCount))

もし、型指定せずに宣言だけした場合 any型 (後述) になります。

基本型の種類

boolean

真偽値です。
true false

number

数値です。浮動小数も含みます。
100 12.3

string

文字列です。
'abcde'

any

any を指定すると、どの型でも格納できるようになります。

let xxx: any

xxx = 1
xxx = false
xxx = 'hello'

型指定が何も指定されていな場合もany型となります。
多用するとTypeScriptを利用している意味が無くなりますが、どうしても判断できないときなどに活用できます。

array

配列です。配列の要素もチェックします。

例えば、以下はエラーになります。

let xxx = [1, 2, 3]
xxx = ["aaa"]
$ tsc test1.ts
test1.ts:2:8 - error TS2322: Type 'string' is not assignable to type 'number'.

2 xxx = ["aaa"]
         ~~~~~


Found 1 error.

要素の型のチェックを緩めたいのであれば、以下のようにします。

let xxx: any[] = [1, 2, 3]
xxx = ["aaa"]

主な型指定方法です。

let array1: number[]
let array2: string[]
let array3: any[]
let array4: Array<number>
let array5: Array<string>
let array6: Array<any>

array in array

多次元配列の場合、以下のようになります。

let nestedArray: number[][] = [[11, 12, 13], [23, 24, 25]]

tuple

配列の各要素ごとに型指定できます。

以下ケースでエラーとなります。

  • 要素ごとに指定した型と異なる型である
  • 要素数が違う
499-typescript-type_tuple.png

enum

enumを利用すると、数値集合を名前付して管理しやすくできます。

enum Kanto {
    Gunma,          // 0
    Tochigi,        // 1
    Ibaraki = 20,   // 20
    Saitama,        // 20
    Tokyo,          // 22
    Chiba = 30,     // 30
    Kanagawa        // 31
}

let prefecture: Kanto = Kanto.Gunma

値は0から自動で割り当てられます。Ibaraki Chiba のように指定することも可能です。

void

voidは 関数の戻り値 で活用されます。
以下のように 戻り値がない ときにvoidを指定します。

const echo = (name: string): void => {
    console.log(`Hello, ${name}`)
}

never

以下のように処理が終了しないので、決して何も返さない場合には、neverを指定します。

let error = (message: string): never => {
    throw new Error(message)
}

object

objectのプロパティも型の制約を持ちます。
以下のコードを例に確認します。

let xxx = {
    aaa: 111,
    bbb: 'hello'
}

xxx = {
    aaa: true,
    bbb: 222
}

xxx = {
    yyy: 111,
    zzz: 'hello'
}

コンパイルすると以下のエラーが検出されました。

$ tsc test1.ts
test1.ts:7:5 - error TS2322: Type 'true' is not assignable to type 'number'.

7     aaa: true,
      ~~~

  test1.ts:2:5
    2     aaa: 111,
          ~~~~~~~~
    The expected type comes from property 'aaa' which is declared here on type '{ aaa: number; bbb: string; }'

test1.ts:8:5 - error TS2322: Type 'number' is not assignable to type 'string'.

8     bbb: 222
      ~~~

  test1.ts:3:5
    3     bbb: 'hello'
          ~~~~~~~~~~~~
    The expected type comes from property 'bbb' which is declared here on type '{ aaa: number; bbb: string; }'

test1.ts:12:5 - error TS2322: Type '{ yyy: number; zzz: string; }' is not assignable to type '{ aaa: number; bbb: string; }'.
  Object literal may only specify known properties, and 'yyy' does not exist in type '{ aaa: number; bbb: string; }'.

12     yyy: 111,
       ~~~~~~~~


Found 3 errors.
  • 値が型と一致しない
  • 存在しないプロパティが定義されている

というエラーです。

なお、明示的に型指定を記述するには以下のようにします。

let xxx: { aaa: number, bbb: string } = {
    aaa: 111,
    bbb: 'hello'
}

object in array

Arrayの中にObjectが存在する場合、以下のようになります。

let arrayInObject1: Array<{ [field: string]: any }>

arrayInObject1 = [
  {aaa: 1, bbb: 2},
  {aaa: 20, ccc: 2},
  {aaa: 22, ddd: "abc"}
]

Objectの中が想定できるのであれば、上記指定より、以下のように interface を定義した方が良いです。

interface Xxx {
  aaa: number;
  bbb?: number;
  ccc?: number;
  ddd?: string;
}
let arrayInObject2: Array<Xxx>

arrayInObject2 = [
  {aaa: 1, bbb: 2},
  {aaa: 20, ccc: 2},
  {aaa: 22, ddd: "abc"}
]

null

null のみ格納できます。

以下のコードは tsconfig.json にて、"strictNullChecks": true となっている場合にエラーとなります。

let xxx: string
xxx = null

もし strictNullChecks を有効なままで null も許容するのであれば、以下のように実装する必要があります。

let xxx: string | null
xxx = null

undefined

undefined のみ格納できます。

参考