###ファクトリ関数
値を生成するための関数。
同じ形式のオブジェクトを何回も作れる。
function Person(n:string, a: number) {
return {
name: n,
age: a,
print: function(){
console.log(this.name)
console.log(this.age)
}
}
}
###オブジェクトの分割代入
type person = { name: { first: string, second: string }, age: number }
const foo:person = { name: { first: 'foo', second: 'bar' }, age: 20 }
const { name: { first, second }, age } = foo
###クラス
class Person {
name: string = 'default'
email?: string
age?: number
print(): void {
// 何らかの処理
}
}
インスタンスのクラスを調べる
インスタンス instanceof クラス // boolean
###インスタンスのクラス名を得る
インスタンス.constructor.name
###継承
class Person {...}
class Student extends Person {}
###アクセス修飾子
プロパティのアクセスを制限する時に
修飾子 | 説明 |
---|---|
public | 外部から自由にアクセス可 |
protected | クラスと継承クラスからアクセス可 |
private | クラス内のみアクセス可 |
###setterとgetter
「直接アクセスされては困るが、完全にアクセスできないのも困る」という時に。
private+setter/getterという使い方が一般的
class Person {
private age: number
get getAge():number {
return this.age
}
set setAge(n:number) {
this.age = n
}
}
インターフェイス
クラスの構造の定義をするためのもの。
インターフェイスで定義したプロパティをクラスは用意しなければならない。
enum School {
junior = 'junior',
juniorHigh = 'juniorHigh',
high = 'high'
}
interface Human {
name: string
print(): void
}
class Person implements Human {
name: string = 'no-name'
mail: string
age: number
constructor(name: string, mail: string = 'no-mail', age: number = -1) {
this.name = name
this.mail = mail
this.age = age
}
print():void {
console.log(this.name)
console.log(this.mail)
console.log(this.age)
}
}
class Student implements Human {
name: string = 'no-name'
school: School
grade?: number
constructor(name: string, school?: School, grade?: number) {
this.name = name
this.school = school
this.grade = grade
}
print():void {
console.log(this.name)
console.log(this.school)
console.log(this.grade)
}
}
利点としては継承関係にないインスタンスをインターフェイスによってまとめられる
const taro: Person = new Person('taro', 'taro@yamada', 20)
const hanako: Student = new Student('hanako', School.high, 2)
const sachiko: Person = new Person('sachiko')
const jiro: Student = new Student('jiro', School.high)
const data:Human[] = [taro, hanako, sachiko, jiro]
###インターフェイスの継承
interface People extends Human {...}
###抽象クラス
interface同様クラスにメソッドを用意するために使用。ただし、抽象クラスに用意される抽象メソッドは実装がないため継承しても使えない。
abstract class Human {
abstract print(): void
}
class Person extends Human {...}
class Student extends Human {...}
###抽象クラスとインターフェイスの違い
- 他にクラスを継承するか?
他のクラスを継承するのであれば、抽象クラスは使用できない
- プロパティを義務付ける必要があるか?
抽象クラスは基本的に「メソッド」を定義するもの。
実装クラスに必ずプロパティをもたせたいなら、インターフェイスを使用
- protectedか、publicか?
インターフェイスはpublicなメソッドを定義。protectedメソッドは使えない。
###静的メンバー
インスタンスを作る必要がないクラス。クラスのプロパティやメソッドを静的メンバーとしてまとめる。
class StaticHuman {
static fullname:string // nameは予約語なので使用できない!
static age:number
static set(nm:string, age:number):void {
this.fullname = nm
this.age = age
}
static print():void {
console.log(this.fullname)
console.log(this.age)
}
}
StaticHuman.set('taro', 40)
StaticHuman.print()
StaticHuman.set('foo', 20)
StaticHuman.print()
###パラメータプロパティ
readonlyを使用。読み取り専用のプロパティを使用できる
class Human {
constructor(readonly name:string, readonly age:number) {}
}
###総称型の利用
class Data<T> {
data?:T[]
constructor(...item:T[]) {
this.data = item
}
print():void {
if (this.data) {
for(let item of this.data) {
console.log(item)
}
} else {
console.log('no data...')
}
}
}
const data1 = new Data<string>('one', 'two', 'three')
const data2 = new Data<number>(1, 2, 3)
###ユーティリティ型
ここでは、Requiredというユーティリティ型を使用している。これにより、Personのhumanプロパティではname, mail, ageのすべての値が必須になる。
type Human = {
name:string
mail?:string
age?:number
}
class Person {
human:Required<Human>
constructor(nm:string, ml:string, ag:number) {
this.human = { name:nm, mail:ml, age:ag }
}
print():void {
console.log(this.human)
}
}