Skip to content

Instantly share code, notes, and snippets.

@turusuke
Last active November 25, 2019 15:26
Show Gist options
  • Save turusuke/5338b9616b05872a5f9cff32a98bebd2 to your computer and use it in GitHub Desktop.
Save turusuke/5338b9616b05872a5f9cff32a98bebd2 to your computer and use it in GitHub Desktop.
ENGINE vol.26 用 playground集

登壇用 playground

記事データ

const article = {
  title: 'タイトル',
  category: 'post',
  published: '2019-01-12',
  tags: ['blog', 'food'],
  content: '今日はいい天気',
}

定義した値と違う型の値をセットしてみる(自動推論機構)

const article = {
  title: 'タイトル',
  category: 'post',
  published: '2019-01-12',
  tags: ['blog', 'food'],
  content: '今日はいい天気',
}

article.title = 12345 // <= Type '12345' is not assignable to type 'string'.

Playground · TypeScript

型注釈をつけてみる

const article: {
  title: string | null, // => 文字列 か null
  category: 'post' | 'page', // => 'post' か 'page'
  published: string, // => 文字列
  tags: string[] | number[], // => 文字列か数値の値を持った配列
  content: string, // 文字列
} = {
  title: 'タイトル',
  category: 'post',
  published: '2019-01-12',
  tags: ['blog', 'food'],
  content: '今日はいい天気',
}

// string | null
// -> 共用体型(Union Types) という型です。
// `|` で複数の型を指定して使います。
// 指定した型のいずれかに該当していることを示しています。

Playground · TypeScript

同じ型定義が必要になったらどうしよう - 単に複製してみる

// 単に複製してみた例
const otherArticle: {
  title: string | null,
  category: 'post' | 'page',
  published: string,
  tags: string[] | number[],
  content: string,
} = {
  title: 'タイトル',
  category: 'post',
  published: '2019-01-12',
  tags: ['blog', 'food'],
  content: '今日はいい天気',
}

Playground · TypeScript

同じ記述は共通化しておきたいですね…

Type alias を使う

// const, let, var のような変数を定義するように、
// 型に名前をつけることができる
type title = string
type category = 'post' | 'page'

type articleType = {
  title: string,
  category: 'post' | 'page',
  published: string,
  tags: string[],
  content: string,
}

// 定義した名前は型注釈の型として実装することができる
const article: articleType = {
  title: 'タイトル',
  category: 'post',
  published: '2019-01-12',
  tags: ['blog', 'food'],
  content: '今日はいい天気',
}

Playground · TypeScript

Interface を試してみる

interface articleInterface {
  title: string;
  category: 'post' | 'page';
  published: string;
  tags: string[] | number[];
  content: string;
}

const article: articleInterface = {
  title: 'タイトル',
  category: 'page',
  published: '2019-01-15',
  tags: [345],
  content: '明日もいい天気',
};

Playground · TypeScript

Interface をクラスに実装してみる

// interface を class に実装してみる
interface GreeterInterface {
  greeting: string
  greet(): string
}

class Greeter implements GreeterInterface {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

let greeter = new Greeter("world");

Playground · TypeScript

Interface を extends で拡張してみる

// extends を使って使って interface を拡張する
interface RobotInterface {
  createdTime: Date
  name: string
  new (name: string)
}

interface extendRobotInterface extends RobotInterface {
  skill: string[]
}

class Robot implements extendRobotInterface {
  createdTime = new Date()
  name: string
  skill: string[]

  constructor(name: string) {
    this.name = name
    this.skill = 12345
  }
}

//let greeter = new Robot('robo-taro');
let greeter = new Robot(12345); // <- 数値を入れようとしているのでエラー(クラス定義部分にエラーがでる)

Playground · TypeScript

どっちもオブジェクト構造を定義できる

// オブジェクト構造を定義できる

type articleType = {
  title: string,
  category: 'post' | 'page',
  published: string,
  tags: string[] | number[],
  content: string,
}

interface articleInterface {
  title: string;
  category: 'post' | 'page';
  published: string;
  tags: string[] | number[];
  content: string;
}

const article: articleType = {
  title: 'タイトル',
  category: 'page',
  published: '2019-01-15',
  tags: [345],
  content: '明日もいい天気',
};

Playground · TypeScript

Interface vs Type alias??

Interface は常に新しい名前を作成する

interface PointInterface {
  x: number
  y: number
}

type PointType = {
  x: number
  y: number
}

const Point_1: PointInterface = {
  x: 1100,
  y: 'hoge' // (property) PointInterface.y: number
}

const Point_2  : PointType = {
  x: 1100,
  y: 'hoge' // (property) y: number
}
PointInterface.y: number // <- Interface の名前が反映されている
(property) y: number // <- 型の情報だけが表示される

値が存在しない場合は type aliase でも名前つきで表示される

const Point_2  : PointType = {
  x: 1100,
  // y: 'hoge'
}
// => Property 'y' is missing in type '{ x: number; }' but required in type 'PointType'.
// const Point_3: PointType

Playground · TypeScript

継承はできる?

type PointType = {
  x: number
  y: number
}

interface PointInterface extends PointType {
  z: number
  add(x: number, y: number, z: number)
}

const Point_1: PointInterface = {
  x: 1100,
  y: 12345,
  z: 5555,

  add(x, y, z) {
    this.x += x
    this.y += y
    this.z += z
  }
}

Playground・TypeScript

Class への型実装ができるのは interface だけ?

type PointType = {
  x: number
  y: number
}

// type を implements できた
class Shape implements PointType {
  x = 0
  y = "error" // <- エラーになるので interface の実装が判別できている
}

type で implements に型の実装を渡すことはできるが、 union 型など type alias は渡せない型もあるので注意

// 交差型を implements に適用してみる
type PointType = {
  x: number
  y: number
}

type OtherPointType = {
  z: number
}

type ExtendsPointType = PointType | OtherPointType

// type を implements できた
class Shape implements ExtendsPointType { // <- 交差型は使えないのでエラーになる
  x = 0
  y = "error"
}

Playground・TypeScript

同名宣言時の扱い

同名のインターフェースが存在していた場合、各メンバーはマージされる

interface Shape {
    x: number,
    y: number
}

interface Shape {
    // x: string <- 同じ名前のプロパティ名が存在している場合、型が違っているとエラーになってしまう
    r: number
}

// interface Greeting {
//     x: number
//     y: number
//     r: number
// }


const shape: Shape = {
    x: 1234,
    y: 5678,
    r: 2345,
}

Playground · TypeScript

同名のメソッドが存在していた場合、各関数はオーバーロードされる

type Morning = "good morning"
type Evening = "good evening"
type Night = "good night"

interface Greeting {
    clone(message: Morning): Morning;
}

interface Greeting {
    clone(message: Evening): Evening;
}

interface Greeting {
    clone(message: Night): Night;
}


// interface Greeting {
//     clone(message: Night): Night;
//     clone(message: Evening): Evening;
//     clone(message: Morning): Morning;
// }


const hoge: Greeting = {
  clone(animal) {
    return animal
  }
}

hoge.clone("good morning")

Playground · TypeScript

type の重複宣言はできない

type Shape = {
    x: number,
    y: number
}

type Shape = {
    // x: string <- 同じ名前のプロパティ名が存在している場合、型が違っているとエラーになってしまう
    r: number
}

const shape: Shape = {
    x: 1234,
    y: 5678,
    r: 2345,
}

Playground・TypeScript

定義されていないプロパティに対する扱い

オブジェクトに定義されていないを追加してみる

type articleType = {
  title: string;
}

interface articleInterface {
  title: string;
}

// interface に存在しない値を追加してみるしてみる
// -> 型注釈でオブジェクトに型付する場合、どちらもエラー
const articleInterface: articleType = {
  title: 'タイトル',
  subTitle: 'サブタイトル'
}

const IarticleInterface: articleInterface = {
  title: 'タイトル',
  subTitle: 'サブタイトル'
}

クラスに存在しないメンバーを追加してみる

type articleType = {
  title: string;
}

interface articleInterface {
  title: string;
}

class articleInterfaceClass implements IarticleInterface {
  title = 'クラスで定義された記事のタイトル'
  newOption = 'happy'
}

class articleTypeClass implements IarticleType {
  title = 'クラスで定義された記事のタイトル'
  newOption = 'happy'
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment