DEV Community

kaede
kaede

Posted on • Edited on

手を動かしながら学ぶ TypeScript Part 2 -- 応用的な型

why

応用的な型も網羅して噛み砕きたくなった。
前回より応用的。


参考

手を動かしながら学ぶ TypeScript
by SmartHR
SECTION-025 TypeScript の型や構文の紹介
P.277 ~

https://www.amazon.co.jp/%E6%89%8B%E3%82%92%E5%8B%95%E3%81%8B%E3%81%97%E3%81%AA%E3%81%8C%E3%82%89%E5%AD%A6%E3%81%B6-TypeScript-%E6%B8%A1%E9%82%89%E6%AF%94%E5%91%82%E6%A8%B9-ebook/dp/B09KZJXDN1


目次

  1. interface
  2. type
  3. class
  4. abstract
  5. union
  6. never
  7. assertion

interface (extends)

interface Creature {
  id: string
}
interface Person extends Creature {
  name: string,
  power: number,
}

const kaede: Person = {
  id: '0902',
  name: 'kaede',
  power: 70,
}
Enter fullscreen mode Exit fullscreen mode

id のみの Creature クラスを定義
それを継承して更に name, power を追加した Person
この Person を使うと、id, name, power の型を使える(必須)。


type (&)

型エイリアス。interface とは違って = が必要。

type Creature = {
  id: string
}
type Person = Creature & {
  name: string,
  power: number,
}

const kaede: Person = {
  id: '0902',
  name: 'kaede',
  power: 70,
}
Enter fullscreen mode Exit fullscreen mode

型エイリアスの type でも
interface の

Person Extends Creature
Enter fullscreen mode Exit fullscreen mode

と同じように

Person = Creature &
Enter fullscreen mode Exit fullscreen mode

で Creature の継承ができた。

なお、先ほどの interface と変数名が同じなので、
同じ階層に先ほどのファイルがあると別名ファイルでも重複エラーになるので注意。


Class

class Student {
  fullName: string

  constructor(firstName:string, lastName:string,) {
    this.fullName = firstName+lastName
  }
}

const Tanaka = new Student('Tanaka', 'Taro')

console.log(Tanaka.fullName);
Enter fullscreen mode Exit fullscreen mode

class でも書ける。
fullName を外部からアクセスできる形で定義して
constructor のなかで計算させる。

継承して new で作り、fullName にアクセスすることができる。

ts-node class.ts
TanakaTaro

実行すると fullName が返ってくる。

しかし、この状態だと lastName は private なので

console.log(Tanaka.lastName);
Enter fullscreen mode Exit fullscreen mode

アクセスすると

Property 'lastName' does not exist on type 'Student'

Student にはないというエラーが出る。

  constructor(firstName:string, public lastName:string,) {
    this.fullName = firstName+lastName
  }
Enter fullscreen mode Exit fullscreen mode

だが、コンストラクタで定義するときに public をつけると

ts-node class.ts
TanakaTaro
Taro

コンストラクタの中身でもアクセスできるようになる。


abstracts/implements

用途不明


Union

どちらかが入る型。
3 つ以上も作れる。
stringNullCheck が false の場合、
全ての型は undfined と null のユニオンになる。

type stringOrNumber =  string | number

const id = 1234
const userId = '1234'
Enter fullscreen mode Exit fullscreen mode

never

何も入らない。

let NoUser: never
NoUser = undefined
Enter fullscreen mode Exit fullscreen mode

Type 'undefined' is not assignable to type 'never'

undefined すらも入らない。


型アサーション

https://qiita.com/irico/items/9d71060e52ffc1e79962

let age = 12
const gender = 'male'
age = gender as any
console.log(age);
console.log(typeof age);
Enter fullscreen mode Exit fullscreen mode

ts-node assertion.ts
male
string

as any をつけることで
最初決めた型を変更して別の型の中身を入れられてしまう。

type teacher = {
  licenseId: string,
  licenseActiveYear: number,
} 
// const BadTeacher:teacher = {}
const NoLicenseTeacher = {} as teacher

console.log(NoLicenseTeacher);
Enter fullscreen mode Exit fullscreen mode

ts-node assertion.ts
{}

また、このように必須のプロパティも無視して型を利用できてしまう。

BadTeacher のように、普通に teacher 型を利用して空で作成すれば
当然必須の型がないのでエラーになる。

しかし、NoLicenseTeacher では as で上書きしてるので teacher の型を使っていてもエラーが出ない!普通に 空オブジェクトで初期化できてしまう。

TypeScript の抜け穴。それがアサーション。

Top comments (0)