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>
}
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 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.
});
@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}
const foo = {ok: 1, ng: 2}
let ok = foo // => ok = 1
// オブジェクトから変数へ代入
あるいは、
{x, y} = foo
は、以下に等しい
x = foo.x
y = foo.y