1. interface의 역할과 class의 역할


interface

・변수에 interface 형태의 타입을 선언할 수 있다.

・new로 인스턴스 생성이 불가능하다 → 주로 프로퍼티나 함수의 형태를 다른 인터페이스나 클래스에서 사용할때 주로 사용된다.

・인터페이스를 임플러먼트한 대상은 해당 인터페이스에 있는 프로퍼티 및 메소드를 반드시 전부 가지거나 구현해야 한다.


②class

・변수에 class 형태의 타입을 선언할 수 있다.

・new로 인스턴스를 생성 가능하다.




2. interface와 class의 상속관계 증명

interface


interface implements interface (X)

interface extends interface (O)

interface implements class (X)

interface extends class (O)



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
interface PersonI {
    name: string;
    age?: number;
}
 
class PersonC{
    name: string;
    age?: number;
}
 
 
// interface implements interface (X)
// Interface declaration cannot have 'implements' clause
interface Korean1 implements PersonI {
    city: string;
}
 
// interface extends interface (O)
interface Korean2 extends PersonI {
    city: string;
}
 
// interface implements class (X)
// Interface declaration cannot have 'implements' clause
interface Korean3 implements PersonC {
    city: string;
}
 
// interface extends class (O)
interface Korean4 extends PersonC {
    city: string;
}
 
const kim: Korean2 = {
    city: 'seoul',
    name'cheolsu'
}
 
const lee: Korean4 = {
    city: 'seoul',
    name'cheolsu'
}
cs




②class


class implements interface (O)

class extends interface (X)

class implements class (O)

class extends class (O)



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
interface PersonI {
    name: string;
    age?: number;
}
 
class PersonC{
    name: string;
    age?: number;
}
 
 
// class implements interface (O)
// implemnts된 name은 반드시 정의 되어야 한다.
class Korean1 implements PersonI {
    name: string;
    city: string;
}
 
// class extends interface (X)
// Cannot extend an interface 'PersonI'. Did you mean 'implements'?
class Korean2 extends PersonI {
    city: string;
}
 
// class implements class (O)
// implemnts된 name은 반드시 정의 되어야 한다.
class Korean3 implements PersonC {
    name: string;
    city: string;
}
 
// class extends class (O)
class Korean4 extends PersonC {
    city: string;
}
 
 
const kim: Korean1 = {
    name'cheolsu',
    city: 'seoul'
}
 
const choi: Korean3 = {
    name'sooyoung',
    city: 'busan'
}
 
const lee: Korean4 = {
    name'cheolsu',
    city: 'seoul'
}
cs

















'frameworks > typescript' 카테고리의 다른 글

TypeScript 핸드북 1 - 기본 타입  (0) 2019.04.24
tsconfig 컴파일 옵션 정리  (0) 2019.04.05
[typescript]decorator  (0) 2018.12.11
[typescript]iterator  (0) 2018.12.11
[typescript]generic(+additional:string literal type)  (0) 2018.12.07

npm とは

  • Node Package Manager の略。
  • JavaScript 系のパッケージを管理するツール。
  • 必要とするパッケージをインストールする際、依存するパッケージもまとめてインストールしてくれる。
  • ライセンスは Artistic License。GPL に似ているが、改造版を再配布する際に名称変更が必要な点が異なる。
  • npm パッケージを集めたリポジトリ (npmjs.com) が運営され、40万ものパッケージが登録されている。

インストール

npm のインストール方法は Node.js のインストール を参照してください。

ヘルプ・バージョン

ヘルプを表示します。

$ npm help
$ npm --help
$ npm help コマンド
$ npm -h コマンド

npm のバージョンを表示します。

$ npm -v
$ npm --version
$ npm version

プロジェクトディレクトリを作成する

npm で管理するプロジェクトディレクトリを作成します。package.json ファイルが生成されます。

$ mkdir my-app
$ cd ./my-app
$ npm init
(略)
package name: (my-app) [Enter]
version: (1.0.0) [Enter]
description: [Enter]
entry point: (index.js) [Enter]
test command: [Enter]
git repository: [Enter]
keywords: [Enter]
author: [Enter]
license: (ISC) [Enter]
(略)
Is this ok? (yes) [Enter]
$ ls -l
-rw-rw-r--.  1 taro taro   298 Jan 18 00:05 package.json

パッケージインストール

カレントディレクトリ配下にインストールします。package.json ファイルが存在するディレクトリで実行します。

$ npm install パッケージ

install の代わりに省略形の i も指定可能です。

$ npm i パッケージ

バージョンを指定してインストールします。

$ npm install パッケージ@x.y.z

-g をつけるとグローバルインストールとなり、システムディレクトリにインストールされます。

$ npm install -g パッケージ
ローカルインストール
カレントディレクトリの node_modules 配下にインストールします。
グローバルインストール
システムディレクトリの node_modules 配下にインストールします。Node.js を yum でインストールしている場合は /usr/lib/node_modu、nodebrew でインストールしている場合は ~/nodebrew/node/バージョン/lib/node_modules 配下などにインストールされます。パッケージに依存するライブラリはローカルインストール、開発時に共通で利用するツールはグローバルインストールするケースも多い様です。

インストール後、package.json へのパッケージ情報追記を制御するには下記のオプションをつけます。

$ npm install パッケージ --no-save            // npm5~
$ npm install パッケージ --save
$ npm install パッケージ --save-optional
$ npm install パッケージ --save-dev
--no-save
package.json に書き込まない場合に指定します。npm4 までは package.json に書き込まないのがデフォルトでしたが、npm5 からは --save がデフォルトとなりました。
--save
依存パッケージの場合に指定します。package.json の dependencies に記録されます。このパッケージを誰かが npm install したときに依存パッケージとしてインストールされます。
--save-optional
依存はするけれど必須ではないパッケージの場合に指定します。package.json の optionalDependencies に記録されます。npm install でインストールされますが、インストールに失敗してもスルーされます。
--save-dev
テストツールなど、開発者が使用するパッケージの場合に指定します。package.json の devDependencies に記録されます。このパッケージを npm install しても、インストールされません。ただし、パッケージを Git から clone して npm install した場合は開発者とみなされ、インストールされます。

package.json に記述されたパッケージを再度インストールするには、package.json が存在するディレクトリで下記を実行します。

$ ls -l
-rw-rw-r--.  1 taro taro   265 Jan 18 01:41 package.json
$ npm install

ただし、インストールされるバージョンは、package.json 記載されたものではなく、最新版がインストールされます。固定のバージョンをインストールするには、npm4 までは shrinkwrap を利用していましたが、npm5 以降では package-lock.json ファイルを使用します。

$ ls -l
-rw-rw-r--.  1 taro taro 14032 Jan 18 01:41 package-lock.json
-rw-rw-r--.  1 taro taro   265 Jan 18 01:41 package.json
$ npm install

また、npm install では、インストールしたバージョンは、--save オプションをつけても package.json ファイルに反映されません。インストールしたパッケージのバージョンを package.json ファイルに反映するには後述の npm-check-updates を利用します。

パッケージ情報

インストール済のパッケージの一覧を表示する

$ npm list
$ npm ls
$ npm la
$ npm ll

グローバルインストールされたパッケージの一覧を見る

$ npm list -g

第一階層のパッケージ(直接インストールしたパッケージ)のみを表示する。

$ npm list --depth=0

パッケージアップデート

インストール済みのものより新しいものがないか確認する。

$ npm outdated
$ npm outdated -g

パッケージをアップデートします。

$ npm update パッケージ
$ npm update パッケージ -g

パッケージ名を省略すると、package.json に記述されたすべてのパッケージをアップデートします。

$ npm update

一括アップデートには、npm-check-updates を使用することもあります。

$ npm install -g npm-check-updates     // ncu をインストールする
$ ncu                                  // アップデート情報を表示する
$ ncu -u                               // アップデート情報を package.json に書き込む
$ npm install                          // 更新された package.json に従いアップデートする
$ ncu パッケージ名                        // 特定のパッケージのみを調べる
$ ncu -x パッケージ名                     // 指定したパッケージを除外する
$ ncu '/^xyz-.*$/'                     // xyz- で始まるパッケージのみを調べる

パッケージアンインストール

アンインストールする

$ npm uninstall パッケージ
$ npm uninstall パッケージ -g

アンインストールの結果を package.json に記録します。

$ npm uninstall --save
$ npm uninstall --save-optional
$ npm uninstall --save-dev

uninstall の代わりに省略系の rm でも可能

$ npm rm パッケージ

パッケージ検索

キーワードに関連するパッケージを npm リポジトリから検索します。

$ npm search パッケージ

パッケージの詳細情報を表示します。

$ npm info パッケージ
$ npm view パッケージ
$ npm show パッケージ

パッケージのバージョンを表示します。

$ npm info パッケージ version  // 最新バージョンを表示
$ npm info パッケージ versions  // インストール可能なバージョン一欄を表示

タスク実行

タスクは package.json の scripts: に記述しておきます。

{
  "scripts": {
    "clean": "rimraf dist/*",
    "build": "npm run clean && tsc",
    "lint": "tslint ./src/**/*.ts --project tsconfig.json",
    "start": "pm2 start pm2config.yaml --env production",
    "test": "jest --coverage"
  }
}

タスクを実行するには run コマンドを使用します。

$ npm run build

引数なしで実行すると、タスクの一覧を表示します。

$ npm run

よく使用されるタスクには下記のものがあります。

$ npm run build   // プロジェクトをビルドします
$ npm run watch   // ファイルの更新を監視し、更新されたら自動ビルドします
$ npm run serve   // 評価用テストサーバを起動します

さらに、複数のタスクを自動実行するには、Grunt や Gulp などのタスクランナーを使用します。

ディレクトリ

ローカル、グローバルのルートディレクトリ、コマンドディレクトリを表示します。

$ npm root
$ npm root -g
$ npm bin
$ npm bin -g



パッケージ生成

該当プロジェクトのPackage化

$ npm pack

.npmignorebにファイルやディレクトリを追加すると記載のものは外してパック化する。



ショートカット

下記のショートカットを利用することができます。

コマンドショートカット
installi
uninstallrm r remove rm un unlink
listls
searchs se
--global-g
--save-S
--save-dev-D


https://stackoverflow.com/questions/29775830/how-to-implement-a-typescript-decorator




General Points

  • Decorators are called when the class is declared—not when an object is instantiated.
  • Multiple decorators can be defined on the same Class/Property/Method/Parameter.
  • Decorators are not allowed on constructors.
























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function editable(isEdit:boolean){
    return function(target:any, propName:string,description:PropertyDescriptor){
        console.log(target);
        console.log('propName:'+propName);
        console.log(description);
 
        target.heyjude = 'heyjude';
    }
}
 
 
class Person{
    constructor(){
        console.log('new Person():');
    }
 
    @editable(true)
    hello(){
        console.log('hello');
    }
}
 
const person = new Person();
person.hello();
console.log(person.heyjude);
 
 
// Person {}
// propName:hello
// { value: [Function: hello],
//     writable: true,
//         enumerable: false,
//     configurable: true }
// new Person():
// heyjude
 
cs





  • target: The prototype of the class (Object).
  • propertyKey: The name of the method (string | symbol).
  • descriptor: A TypedPropertyDescriptor — If you're unfamiliar with a descriptor's keys, I would recommend reading about it in this documentation on Object.defineProperty (it's the third parameter).
※decorator는 선언과 동시에 콜되기 때문에, const person = new Person();초기화되지 않아도 class Person{...}만으로 실행된다.




































'frameworks > typescript' 카테고리의 다른 글

tsconfig 컴파일 옵션 정리  (0) 2019.04.05
interface와 class의 상속관계 증명  (0) 2019.02.07
[typescript]iterator  (0) 2018.12.11
[typescript]generic(+additional:string literal type)  (0) 2018.12.07
[typescript]class  (0) 2018.12.07



















































'frameworks > typescript' 카테고리의 다른 글

interface와 class의 상속관계 증명  (0) 2019.02.07
[typescript]decorator  (0) 2018.12.11
[typescript]generic(+additional:string literal type)  (0) 2018.12.07
[typescript]class  (0) 2018.12.07
[typescript]interface  (0) 2018.12.06









*타입이 정해지지 않았을 때 타입을 변수처럼 전달 할 수 있다.








*generic을 포함하는 함수나 클래스를 부르는 두가지 방법


1
2
3
4
5
6
7
8
function test<T>(test: T): T{
    alert(test);
    return test;
}
 
//string인 'haha'의 형태를 자동 추론하여, <T>=<string>으로 인식한다.
test('haha');

//generic을 명시적으로 전달해준다.
test<string>('haha');
 
cs

 












































*string literal type : 스트링 리터럴타입이란, 스트링타입의 서브타입의 일종으로 스트링타입에 제약을 하나 더붙여서 특정 문자열만 허가 하도록 하는 형태로 컴파일시 타입체크의 타겟이 된다. string타입의 서브타입이므로 string이 가진 함수에 접근할 수 있다.

 이와같은 성질은 number literal type에서도 마찬가지이다.


//string literal typeconst eventName1: "click" = "click"; // OK
const eventName2: "click" = null; // OK
const eventName3: "click" = undefined; // OK

// Error: Type '"mouseover"' is not assignable to type '"click"'.
const eventName4: "click" = "mouseover";

// Error: Type '""' is not assignable to type '"click"'.
const eventName5: "click" = "";const eventName5: "click"|"mouseover"; = "click";
//number literal typeconst eventNum1: 3 = 3; // OK const eventNum2: 3 = null; // OK const eventNum3: 3 = undefined; // OK // Error: Type '5' is not assignable to type '3'. const eventNum4: 3 = 5; // Error: Type '""' is not assignable to type '"click"'. const eventNum5: 3 = "";




*keyof 는 인터페이스나 클래스가 지닌 key를 스트링 리터럴 타입의 유니온으로 만들어준다.


interface Person {
    name: string;
    age: number;
    location: string;
}

type K1 = keyof Person; // "name" | "age" | "location"
type K2 = keyof Person[];  // "length" | "push" | "pop" | "concat" | ...
type K3 = keyof { [x: string]: Person };  // string


































'frameworks > typescript' 카테고리의 다른 글

[typescript]decorator  (0) 2018.12.11
[typescript]iterator  (0) 2018.12.11
[typescript]class  (0) 2018.12.07
[typescript]interface  (0) 2018.12.06
[typescript]type assertion  (0) 2018.12.06


*class의 역할과 interface의 역할

1.class

・변수에 class 형태의 타입을 선언할 수 있다.

・new로 인스턴스를 생성할 수 있다.


2.interface

・변수에 interface 형태의 타입을 선언할 수 있다.

・new로 인스턴스 생성이 불가능하다.

・인터페이스를 임플러먼트한 대상은 해당 인터페이스에 있는 프로퍼티 및 메소드를 반드시 전부 가지거나 구현해야 한다.


※class의 extends,implements의 관계는 다른 포스트에서 다룬다.







































*suepr의 예

-부모 클래스의 constructor을 불러 사용할 때 필요한 키워드(27행)

-자식 클래스에서 부모 클래스의 public한 메소드에 엑세스할때 필요한 키워드(32행)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Rectangle {
    name: string = null;
    height: number = null;
    width: number = null;
 
    constructor(height, width) {
        this.name = 'Rectangle';
        this.height = height;
        this.width = width;
    }
 
    sayName() {
        console.log('Hi, I am a ', this.name + '.');
    }
 
    getArea() {
        return this.height * this.width;
    }
 
    setArea(value) {
        this.height = this.width = Math.sqrt(value);
    }
}
 
class Square extends Rectangle {
    length: number = null;
 
    constructor(length) {
        super(lengthlength);
        this.name = 'Square';
    }

copiedFunc = super.getArea; // same as this.getArea;
}
 
const rectangle:Rectangle= new Rectangle(34);
console.log(rectangle.getArea());
 
const square: Square = new Square(8);
console.log(square.name); //Square
console.log(square.getArea()); //64
console.log(square.copiedFunc()); //64
cs









*constructor에서 property바로 할당하기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Person{
    protected _name: string = null;
    private _age: number = null;
    constructor(protected name:string,age:number) {
        this._name= name;
        this._age= age;
    }
    hello(): void{
        console.log(this._name);
    }
}
const person:Person = new Person('mark'23);
person.hello();
 
//==============>
class Person{
    constructor(protected _name:string,private _age:number) {}
 
    hello(): void{
        console.log(this._name);
    }
}
 
const person: Person = new Person('mark'23);
person.hello();
cs





























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Person_getterSetter{
    private _name: string = null;
    private _age: number = null;
    private _salary: number = null;
 
    constructor(name:string,age:number) {
        this._name = name;
        this._age = age;
    }
 
    get salary():number {
        return this._salary;
    }
 
    set salary(money:number) {
        this._salary = money;
    }
}
 
class Person_noGetterSetter{
    private _name: string = null;
    private _age: number = null;
    private _salary: number = null;
 
    constructor(name:string,age:number) {
        this._name = name;
        this._age = age;
    }
 
    getSalary():number {
        return this._salary;
    }
 
    setSalary(money:number) {
        this._salary = money;
    }
}
 
const p1: Person_getterSetter = new Person_getterSetter('mark'29);
p1.salary = 10000;
console.log(p1.salary);
 
const p2: Person_noGetterSetter = new Person_noGetterSetter('jake'32);
p2.setSalary(20000);
console.log(p2.getSalary());
cs



























싱글톤 패턴


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Person{
    private static instance: Person = null
    private testProperty: string;
 
    private constructor() {
    }
 
    public static getInstance(): Person{
        if (Person.instance===null) {
            Person.instance = new Person();
        }
 
        return Person.instance;
    }
 
    hello(): void{
        console.log('hello world');
    }
 
        setTestProperty(param: string): void{
        this.testProperty = param;
    }
 
    getTestProperty(): string{
        return this.testProperty;
    }
}
 
const p2: Person = Person.getInstance();
p2.setTestProperty('instance1');
console.log(p2.getTestProperty()); // instance1
 
const p3: Person = Person.getInstance()
console.log(p3.getTestProperty()); // instance1
cs






class의 형변환 : <targetType>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 
class Rectangle {
    name: string = null;
    height: number = null;
    width: number = null;
 
    constructor(height, width) {
        this.name = 'Rectangle';
        this.height = height;
        this.width = width;
    }
 
    sayName() {
        console.log('Hi, I am a ', this.name + '.');
    }
 
    getArea() {
        return this.height * this.width;
    }
 
    setArea(value) {
        this.height = this.width = Math.sqrt(value);
    }
}
 
class Square extends Rectangle {
    feature = 'length of all line is same';
    length: number = null;
 
    constructor(length) {
        super(lengthlength);
        this.name = 'Square';
    }
    copiedFunc = super.getArea; // same as this.getArea;
}
function castingFn(param: Rectangle) {
    const castedProperty = <Square>param; // 형변환
    console.log(castedProperty.feature);
}
 
const square: Square = new Square(8);
castingFn(square);
 
const square2: Rectangle = new Square(8);
square2.feature; // 컴파일 실패 : Square의 프로퍼티를 Rectangle로 형을 제한한 후 사용하려하기 때문
           















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
interface ICar{
    honk(): void;
    accelerate(speed: number): void;
    getSpeed(): number;
}
 
class Car implements ICar{
    private _name:string = null;
    private _speed:number = 0;
 
    constructor(name:string) {
        this._name = name;
    }
 
    public honk():void {
        console.log('부우우웅');
    }
 
    public accelerate(speed: number):void{
        this._speed = this._speed + speed;
    }
 
    //getter,setter
    public getSpeed(): number{
        return this._speed;
    }
 
}
 
const car: Car = new Car('benz');
car.honk();
console.log(car.getSpeed());
car.accelerate(10);
console.log(car.getSpeed());
cs








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
interface IBase{
    width: number;
    length: number;
}
 
class CBase{
    protected width: number =0;
    protected length: number=0;
}
 
class Rectangle_inter implements IBase{
    public width = null;
    public length = null;
 
    constructor(width,length) {
        this.width = width;
        this.length = length;
    }
 
    area(): number{
        return this.width * this.length;
    }
}
 
class Rectangle_class extends CBase{
    constructor(width,length) {
        super();
        this.width = width;
        this.length = length;
    }
 
    public area(): number{
        return this.width * this.length;
    }
}
 
const rectangle_inter: Rectangle_inter = new Rectangle_inter(86);
console.log(rectangle_inter.area());
 
const rectangle_class: Rectangle_class = new Rectangle_class(86);
console.log(rectangle_class.area());
cs








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class CPerson{
    _firstName: string;
}
 
class Person extends CPerson{
 
    get firstName(): string{
        return this._firstName;
    }
 
    set firstName(value: string){
        if (value.length > 3) {
            this._firstName = value;
        }
        else {
            this._firstName = 'name is under 3chars';
        }
    }
}
 
const person: Person = new Person();
person.firstName = 'ma';
console.log(person.firstName);
 
person.firstName = 'jenny';
console.log(person.firstName);
cs












'frameworks > typescript' 카테고리의 다른 글

[typescript]iterator  (0) 2018.12.11
[typescript]generic(+additional:string literal type)  (0) 2018.12.07
[typescript]interface  (0) 2018.12.06
[typescript]type assertion  (0) 2018.12.06
[typescript]type  (0) 2018.12.06



























1
2
3
4
5
6
7
8
9
10
11
interface Person{
    name:string;
    [index:string]:string;
}
 
const person:Person={
    name:'mark'
    indexableVar:'test'
}
 
 
cs


[index:string]에서 string 자리에 올수 있는건 number혹은 string 뿐이다.
















































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
interface Iperson{
    name: string;
    hello(): void;
}
 
class Person implements Iperson{//Person클래스에서 프로퍼티 name과 hello()는 반드시 구현되어야한다.
    name = null;
 
    constructor(name: string) {
        this.name = name;
    }
 
    hello(): void{
        console.log(`hello, my name is ${this.name}`);
    }
 
    hi(): void{
        console.log(`hi, my name is ${this.name}`);
    }
}
 
const p1:Person = new Person('minsu');
const p2:Iperson = new Person('sooji');
 
p1.hello();
p1.hi();
 
p2.hello();//p2는 Iperson클래스 이므로 hi()를 가지고 있지 않다.
cs








'frameworks > typescript' 카테고리의 다른 글

[typescript]iterator  (0) 2018.12.11
[typescript]generic(+additional:string literal type)  (0) 2018.12.07
[typescript]class  (0) 2018.12.07
[typescript]type assertion  (0) 2018.12.06
[typescript]type  (0) 2018.12.06

+ Recent posts