Skip to content

Instantly share code, notes, and snippets.

@externvoid
Last active June 2, 2020 00:35
Show Gist options
  • Save externvoid/757d60d9c9ea3c028eb93236d6324445 to your computer and use it in GitHub Desktop.
Save externvoid/757d60d9c9ea3c028eb93236d6324445 to your computer and use it in GitHub Desktop.
TypeScriptのミソ

C言語構造体宣言

struct point {
  float: x;
  float: y;
};

あるいは、

typedef struct {
  float: x;
  float: y;
} Vector;

使い方

struct point p1, p2;
Vector v1, v2;

同様なオブジェクトの型定義

interface Vector {
  number: x
  number: y
}

型定義に省略可能なプロパティーを含める事が出来る

interface Vector {
  number: x
  number: y
  descripton?: string // 座標、ベクトル
}

セミコロンの省略

JavsScriptとTypeScriptではセミコロンの省略がサポートされている。ただし、次のコードはコンパイル不可。括弧で始まる行の前行にはセミコロンが必要。 この機能は、ASI、自動セミコロン挿入と呼ばれる。

const str = 'String' // => TypeError: "String" is not a function                
(new Array()).push(1)
console.log( (new Array()).push(2) ) // => 2

関数定義には型注釈が必要

function hello(name: string): string {
  return `Hello ${name}`
}
hello('foo') // => Hello foo

引数の型が関数の場合の型注釈の書き方

function onSuccess(callback: (value: string) => void) {
  callback('成功')
}
onSuccess(value => console.log(value))

アロー関数の型注釈の書き方

const add = (a: number, b: number): number => { return a + b }

オブジェクトを引数に取る関数の型注釈

function hello2(person: {id: number, name: string}): string {
  return `Hello ${person.id} ${person.name}`
}
hello2(1, 'foo') // => Hello 1 foo

これが、

interface Person {
  id: number
  name: string
}
function hello3(person: Person):string {
  return `Hello ${person.id} ${person.name}`
}

オブジェクト引数関数の曖昧引数解釈

{id: number, name: string}を引数に要求する関数に、{id: number, name: string, description: string}を与えても構わない。

省略可能関数引数、デフォルト関数引数

function hello4(name?: string) {
  return `Hello ${name || "Anonimous"}`
}
hello4() // => Hello Anonimous

デフォルト関数引数があれば、引数へ型注釈が不要

function hello5(name = 'Anonimous') {
  return `Hello ${name}`
}
hello5() // => Hello Anonimous

ジェネリクス関数の定義と呼出

汎用型Tを三角括弧<>で記述する。

function foo<T>(arg: T): T {
  return arg
}
foo<string>('bar') // => bar

特殊型anyを使えば、ジェネリクス関数定義せずに似た事ができる。

function kaz(arg: any): any {
  return arg
}
kaz('qux') // => qux

ジェネリクス・クラス定義とインスタンス生成

インスタンス変数はdefaultでpublicアクセス指定。

class A<T> {
  prop1 = 'initial instance variable'
  private prop2 = 'private variable'
  constructor(x: T) {}
}
let a = A<number>(1)
console.log(a.prop1) // => initial instance variable

型変換

2通りの記法がある

let str: any = '1'
<number>str + 2 // => 3

let num: number = str as number

JSXを使用する場合には、前者はNG。 これはOK

function render(nickname: string, id: string) {
  return React.createElement("div", {"class": "nickname"}, nickname + <number>id)
}

JSXはこうする。JSXの三角括弧は、仮想タグを表すので、型変換と仮想タグの区別を付けるため!

function render (nickname: string, id: string) {
  return <div className="nickname">nickname + id as numbrer</div>
}

ES6のブロックスコープ

JavaScriptではカーリーブラケットでブロックを表現できる。let, constはブロック内にスコープ限定できるが、varは限定出来ない。

{
  let foo = 1
  var bar = 2
}
foo // => undefined
bar // => 2

ただし、関数定義内で宣言された変数のスコープは、関数ブロックスコープである。

function foo() {
  var a = 100
}
foo()
a // => undefined
function bar() {
  b = 1000
}
b // => undefined
bar()
b // => 1000

未宣言の変数はグローバルとなるのが奇妙な所!

constオブジェクトとは再代入不可オブジェクト(immutable object)

const a = {}
a.that = 100 // => 100
a = {} // TypeError: Assignment to constant variable.

再代入不可、別のオブジェクトをaにpointさせることは出来ない。 オブジェクトのメンバを変更する事はできる。変更不能にするには、

Object.freeze(a)
a.that = 200 // Oops No. Error!
a.that // => 100

似たものにsealメソッドがあって、既存メンバの変更は可能だが、メンバの追加が出来ない。

const a = {}
a.that = 1
a // => {that: 1}
Object.seal(a)
a.that = 2 // => {that: 2}
a.these = 10 // => {that: 2}

freeze, sealに関連してプロパティー・記述子の編集ができる。configurableプロパティー記述子をfalseとすれば、プロパティーの削除が不可能となる。

var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});

TypeScriptのデコレーター

@sealed
class Greeter {
  greeting: string
  constructor(message: string) {
    this.greeting = message
  }
  greet() {
    return "Hello" + this.greeting
  }
}

GreeterはObject.seal()される。

オブジェクトの取り込み

const foo = {a: 1, b: 2}
const bar = Object.assign({c: 3}, foo}
bar // => {c: 3, a: 1, b: 2}

分割代入、de-structuring assignment、構造破壊型代入

const foo = {ok: 1, ng: 2}
let ok = foo // => ok = 1
// オブジェクトから変数へ代入

あるいは、

{x, y} = foo

は、以下に等しい

x = foo.x
y = foo.y

curly braces in javascript variables

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment