https://medium.com/@seungha_kim_IT/typescript-enum%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0-3b3ccd8e5552




TypeScript enum을 사용하는 이유


(본 글은 TypeScript 입문자 중 enum 기능이 있는 다른 언어를 사용해 본 경험이 없는 분들을 위해 쓰여졌습니다. 예제 코드를 TypeScript playground에 붙여 넣고, 마우스 포인터를 변수 위에 둬서 변수의 타입이 어떻게 지정되는지 확인해보세요.)

TypeScript enum은 JavaScript에는 없는 개념으로, 일견 상수, 배열, 혹은 객체와 비슷해보이기도 합니다. 그냥 상수, 배열, 객체를 써도 될 것 같은데, 굳이 enum을 쓰는 이유가 뭘까요?

Enum은 추상화의 수단

다국어 지원을 위해 언어 코드를 저장할 변수를 만들어야 하는 상황을 생각해봅니다.

const code: string = 'en' // string?

제품이 지원할 수 있는 언어는 사전에 정해져있는데, 이 값이 할당될 변수를 string 타입으로 지정하는 것은 범위가 너무 넓은 것 같다는 느낌이 듭니다. 이를 개선해봅시다.

일단은 리터럴 타입과 유니온을 이용해 code 변수에 대한 타입의 범위를 좁혀줄 수 있습니다.

type LanguageCode = 'ko' | 'en' | 'ja' | 'zh' | 'es'const code: LanguageCode = 'ko'

이제 code 변수에 ‘zz’ 같이 이상한 값을 대입하면 컴파일 에러가 납니다. 타입의 범위는 원하는대로 좁혀졌습니다.

하지만 코딩을 하다보니, 제품이 어떤 언어를 지원하기로 했었는지도 가물가물하고, 특정 국가 코드가 정확히 어떤 언어를 가리키는지 일일이 외우기도 쉽지 않습니다. 이 때 상수를 여러 개 둬서 문제를 해결할 수는 있지만, 그닥 깔끔한 느낌은 아닙니다.

const korean = 'ko'
const english = 'en'
const japanese = 'ja'
const chinese = 'zh'
const spanish = 'es'
// 이렇게 하면 언어 코드가 위아래에 중복되고
type LanguageCode = 'ko' | 'en' | 'ja' | 'zh' | 'es'
// 이렇게 하면 코드가 너무 길어집니다
// type LanguageCode = typeof korean | typeof english | typeof japanese | typeof chinese | typeof spanish
const code: LanguageCode = korean

이런 경우에 enum을 사용해 리터럴의 타입과 값에 이름을 붙여서 코드의 가독성을 크게 높일 수 있습니다.

export enum LanguageCode {
korean = 'ko',
english = 'en',
japanese = 'ja',
chinese = 'zh',
spanish = 'es',
}
// 여기서
// LanguageCode.korean === 'ko'
// (의미상) LanguageCode === 'ko' | 'en' | 'ja' | 'zh' | 'es'
const code: LanguageCode = LanguageCode.korean

짧은 코드로 타입의 범위도 좁히고, 가독성도 높일 수 있게 되었습니다.

enum은 객체

TypeScript enum은 그 자체로 객체이기도 합니다.

const keys = Object.keys(LanguageCode) // ['korean', 'english', ...]const values = Object.values(LanguageCode) // ['ko', 'en', ...]

그렇다면 그냥 객체를 사용하는 것과는 어떤 차이점이 있을까요?

1. 객체는 (별다른 처리를 해주지 않았다면) 속성을 자유로이 변경할 수 있는데 반해, enum의 속성은 변경할 수 없습니다.

2. 객체의 속성은 (별다른 처리를 해주지 않았다면) 리터럴의 타입이 아니라 그보다 넓은 타입으로 타입 추론이 이루어집니다. enum은 항상 리터럴 타입이 사용됩니다.

3. 객체의 속성 값으로는 JavaScript가 허용하는 모든 값이 올 수 있지만, enum의 속성 값으로는 문자열 또는 숫자만 허용됩니다.

정리하자면, 같은 ‘종류’를 나타내는 여러 개의 숫자 혹은 문자열을 다뤄야 하는데, 각각 적당한 이름을 붙여서 코드의 가독성을 높이고 싶다면 enum을 사용하세요. 그 외의 경우 상수, 배열, 객체 등을 사용하시면 됩니다.

ps. 다만, 객체 리터럴에 대해 상수 단언(const assertion)을 해준다면 이 객체를 enum과 비슷한 방식으로 사용할 수 있습니다. 상수 단언에 대해서는 제가 쓴 다른 글도 참고해주세요.

const languageCodes = {
korean: 'ko',
english: 'en',
japanese: 'ja',
chinese: 'zh',
spanish: 'es',
} as const // const assertion
// 속성 값을 변경할 수 없음
// 속성의 타입으로 리터럴 타입이 지정됨
type LanguageCode = typeof languageCodes[keyof typeof languageCodes]const code: LanguageCode = languageCodes.korean

ps. TypeScript에는 enum의 속성 값을 명시적으로 지정해주지 않아도 자동으로 0부터 시작하는 정수들이 지정되는 기능이 있습니다. 한 번 검색해보세요.

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

TypeScript 핸드북 1 - 기본 타입  (0) 2019.04.24
tsconfig 컴파일 옵션 정리  (0) 2019.04.05
interface와 class의 상속관계 증명  (0) 2019.02.07
[typescript]decorator  (0) 2018.12.11
[typescript]iterator  (0) 2018.12.11

기본 Type

소개

프로그램을 구조적으로 잘 만들기 위해 number, string, structure, boolean 등 가장 간단한 데이터 단위로 작업을 할 수 있어야합니다. TypeScript에서는 이러한 타입들을 JavaScript와 거의 같은 형태로 지원합니다.

Boolean

JavaScript/TypeScript의 가장 기본적인 데이터 타입은 true/false 값을 가지는 boolean 입니다.

let isDone: boolean = false;

Number

JavaScript에서와 마찬가지로 TypeScript의 모든 숫자는 부동 소수점 값이고 number 타입을 가집니다. TypeScript는 16 진수 및 10 진수 리터럴 외에도 ECMAScript 2015에 도입된 바이너리 및 8 진수를 지원합니다.

let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;

String

웹 페이지와 서버용 JavaScript에서 프로그램을 생성할 때 흔히 문자열 데이터를 많이 사용합니다. 다른 언어에서와 마찬가지로, TypeScript에서 이러한 문자 데이터 유형을 나타 내기 위해 string 타입 문자열을 사용합니다. JavaScript와 마찬가지로 TypeScript는 문자열 데이터를 표현하기 위해 큰 따옴표(“) 또는 작은 따옴표(‘)를 사용합니다.

let color: string = "blue";
color = 'red';

문자열이 여러 행에 걸쳐 있고 표현식을 포함할 수있는 template string을 사용할 수도 있습니다. 이러한 문자열은 백틱/백 쿼트(` ) 문자로 둘러싸여 있있고, ${expr}를 이용하여 표현식을 포함할 수 있습니다.

let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${fullName}.
I'll be ${ age + 1 } years old next month.`;

위 코드는 String 변수를 다음과 같이 선언하는 것과 같습니다.

let sentence: string = "Hello, my name is " + fullName + ".\n\n" +
    "I'll be " + (age + 1) + " years old next month.";

Array

TypeScript는 JavaScript와 마찬가지로 배열을 사용할 수있습니다. 배열 타입은 두 가지 방법 중 하나로 작성할 수 있습니다. 첫 번째로, 각 타입에 []를 붙여 해당 타입의 배열을 나타냅니다

let list: number[] = [1, 2, 3];

두 번째 방법은 일반적인 배열 타입 Array을 사용합니다.

let list: Array<number> = [1, 2, 3];

Tuple

튜플 타입을 사용하면 고정된 수의 요소 타입은 알고 있지만, 값의 종류가 다른 배열을 표현할 수 있습니다. 예를 들어, 문자열과 숫자의 쌍을 아래와 같이 표현할 수 있습니다.

// Declare a tuple type
let x: [string, number];
// Initialize it
x = ["hello", 10]; // OK
// Initialize it incorrectly
x = [10, "hello"]; // Error

변수 선언에 포함된 인덱스 요소의 타입은 인덱스를 이용하여 정확한 타입으로 액세스가 가능합니다. 하지만, 타입이 서로 다를수 있기 때문에 액세스한 데이터의 처리는 달라질 수 있습니다.

console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 'number' does not have 'substr'

변수 선언에 포함되지 않는 요소에 대한 액세스는 Tuple 선언에 사용된 타입의 Union 타입으로 사용됩니다.

x[3] = "world"; // OK, 'string' can be assigned to 'string | number'
console.log(x[5].toString()); // OK, 'string' and 'number' both have 'toString'
x[6] = true; // Error, 'boolean' isn't 'string | number'
Union 타입은 이후 장에서 다룰 고급 주제중 하나 입니다.

Enum

JavaScript의 표준 데이터 타입에서 유용한 기능중 하나는 enum입니다. C# 언어와 마찮가지로 enum은 숫자값 데이터 셋에 사람이 더 친숙한 이름을 지정하는 방법입니다.

enum Color {Red, Green, Blue}
let c: Color = Color.Green;

기본적으로 enum은 0부터 시작하여 멤버의 번호 매기기를 시작합니다. 멤버 중 하나의 값을 수동으로 설정하여 변경할 수 있습니다. 예를 들어 이전 예제를 0 대신 1로 시작할 수 있습니다.

enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;

또는 enum의 모든 값을 수동으로 설정할 수 있습니다.

enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;

enum의 편리한 기능은 숫자 값에서 enum의 값 이름으로 이동할 수 있다는 것입니다. 예를 들어 값이 2이지만 위의 색상 enum에 매핑된 것이 확실하지 않은 경우 해당 이름을 찾을 수 있습니다.

enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
alert(colorName);

Any

값을 자신 또는 타사 라이브러리의 동적 콘텐츠에서 가져오는 것과 같이 프로그램을 작성할 때 알지 못하는 변수 유형을 설명해야 할 수도 있습니다. 이 경우 컴파일시 타입 검사를 하지 않고 지나가도록 해야 합니다. 이런 방법을 위해 any 타입을 사용합니다.

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean

any 타입은 기존 JavaScript와 같이 작업하는 강력한 방법중 하나 입니다. 컴파일하는 동안 타입 검사를 옵트 인 (opt-in)하거나 옵트 아웃 (opt-out) 할 수 있습니다. 다른 언어도 비슷하지만 JavaScript의 Object 타입이 비슷한 역할을 합니다. 그러나 Object 타입의 변수는 값을 할당할 수만 있습니다. 실제 존재하는 메소드라도 임의의 메소드를 호출할 수는 없습니다 :

let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)
let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.

any 타입은 타입의 일부분을 알고 있다면 편리하지만 그렇지 않을 수도 있습니다. 예를 들어 배열이 있고, 배열에 있는 값은 다른 타입이 혼합되어 있을 수 있습니다.

let list: any[] = [1, true, "free"];
list[1] = 100;

Void

void는 타입이 전혀 없다는 것에서 any의 반대 의미와 비슷합니다. 일반적으로 값을 반환하지 않는 함수의 반환 유형으로 이 타입을 사용합니다.

function warnUser(): void {
    alert("This is my warning message");
}

void 타입의 변수 선언은undefined 또는null 만 할당할 수 있기 때문에 그다지 유용하지 않습니다.

let unusable: void = undefined;

Null 과 Undefined
TypeScript에서 undefined와 null은 실제로 각각 undefined와 null이라는 이름의 타입을 가지고 있습니다. void와 매우 비슷하게, 이 타입들은 그 자체로 매우 유용하지는 않습니다.

// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;

기본적으로 null과 undefined는 다른 모든 유형의 하위 유형입니다. 즉,null과 undefined를 number와 같은 것에 할당할 수 있습니다.

--strictNullChecks 플래그를 사용할 경우 null과 undefined는 void와 각각의 타입 변수에만 할당 가능합니다. 이렇게하면 많은 일반적인 오류를 피할 수 있습니다. string 또는 null 또는 undefined를 전달 하고자하는 경우, union 타입 string|null|undefined을 사용할 수 있습니다. 다시 한번, Union 타입은 후반부에 자세히 설명합니다.

가능하면 --strictNullChecks의 사용을 권장합니다. 그러나이 핸드북의 목적 상 우리는 플래그가 꺼져 있다고 가정 합니다.

Never

never 타입은 절대로 발생하지 않는 값의 타입을 나타냅니다. 예를 들어, never는 함수 표현식의 리턴 타입이거나, 항상 예외를 던지는 화살표 함수 표현식이거나, 리턴하지 않는 표현식입니다. 변수는 결코 true가 될 수없는 어떤 타입의 가드에 의해 좁혀 질 때 타입 never를 획득합니다.(?)

never 타입은 모든 타입의 서브 타입이며, 모든 타입에 assign 가능합니다. 하지만 어떤 타입도 never (never 자체 제외)의 하위 타입이 아니고 assign 할 수 없습니다. 어떤 타입도 ‘never’에 assign되지 않습니다.

‘never’를 반환하는 함수의 몇 가지 예는 다음과 같습니다.

// Function returning never must have unreachable end point
function error(message: string): never {
    throw new Error(message);
}
// Inferred return type is never
function fail() {
    return error("Something failed");
}
// Function returning never must have unreachable end point
function infiniteLoop(): never {
    while (true) {
    }
}

Object

object는 non-primitive 타입, 즉 number, string, boolean, symbol, null 또는undefined가 아닌 타입을 나타내는 타입입니다.

object 타입을 사용하면 Object.create와 같은 API를보다 잘 표현할 수 있습니다.

declare function create(o: object | null): void;
create({ prop: 0 }); // OK
create(null); // OK
create(42); // Error
create("string"); // Error
create(false); // Error
create(undefined); // Error

Type assertions

어떤 값에 대해 프로그래머는 때때로 TypeScript보다 더 많은 정보를 알수 있습니다. 보통 이런 경우는 어떤 엔티티의 타입이 현재 타입보다 더 구체적인 타입을 알고 있을 때입니다.

타입 어설션은 컴파일러에게 “나를 믿어. 내가 하고 있는 일을 잘 알아.”라고 말하는 방법입니다. 타입 어설션은 다른 언어의 타입 변환과 비슷하지만 특별한 검사 나 데이터 재구성을 수행하지 않습니다. 런타임에 영향을 미치지 않으며 컴파일러에서만 사용됩니다. TypeScript는 프로그래머가 필요한 특수 검사를 수행했다고 가정합니다.

타입 어설션에는 두 가지 형식이 있습니다. 하나는 “angle-bracket(<>)”구문입니다.

let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;

그리고 다른 하나는 as 구문입니다 :

let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;

두가지 방법은 동일한 역할을 하기 때문에 어떤것을 사용하는지는 단지 선택의 문제입니다. 그러나 TypeScript를 JSX와 함께 사용할 경우는 as 스타일의 어설션만 허용됩니다.

let에 대해

지금까지 우리는 기존에 알고있는 JavaScript의 var 키워드 대신 let 키워드를 사용했습니다. let 키워드는 실제로 TypeScript에서 사용할 수있는 더 새로운 JavaScript 구문입니다. 나중에 자세한 내용을 다루 겠지만, 자바 스크립트의 많은 일반적인 문제는 let을 사용하여 완화되므로 가능할 때마다 var 대신 사용하십시오.

이 내용은 나중에 참고하기 위해 제가 공부하며 정리한 내용입니다.
의역, 오역, 직역이 있을 수 있음을 알려드립니다.
This post is a translation of this original article [https://www.typescriptlang.org/docs/handbook/basic-types.html]

참고

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

enum을 사용하는 이유  (0) 2020.02.03
tsconfig 컴파일 옵션 정리  (0) 2019.04.05
interface와 class의 상속관계 증명  (0) 2019.02.07
[typescript]decorator  (0) 2018.12.11
[typescript]iterator  (0) 2018.12.11

tsconfig.json 옵션정리

퍼온자료입니다

tsconfg.json

{
  "compilerOptions": {
    "target": "ES2017", // 사용할 ECMAScript 버전 설정

    /////////// module ///////////
    "module": "CommonJS", // 모듈 설정
    "moduleResolution": "node", // 모듈 (검색)해석 방식 설정
    "allowSyntheticDefaultImports": true, // export default 를 export 한 값들을 가지는 객체로 설정
    "esModuleInterop": true, // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html

    /////////// path ///////////
    "baseUrl": ".", // Non-relativ 모듈 혹은 paths 옵션의 기준 디렉토리
    "paths": { // baseUrl 옵션을 기준디렉토리로 불러올 모듈의 위치 설정이 가능
      "*": ["*"]
    }, 
    // "rootDirs": [ ], // 가상 디덱토리를 설정
    // "rootDir": "./", // 입력파일의 rootDir 설정
    // outDir옵션을 사용할때만 사용
    // "outDir": "dest", // 출력할 디덱토리
    // "outFile": "", // 단일파일로 출력시 파일명

    /////////// declaration ///////////
    "declaration": false, // .d.ts 파일의 생성 여부
    // "declarationDir": "", // .d.ts 파일이 생성되는 디렉토리 설정

    /////////// log ///////////
    "diagnostics": false, // Show diagnostic information.
    "traceResolution": false, // 모듈 검색에 대한 로그메세지 출력 여부
    "listEmittedFiles": false, // 컴파일된 결과 파일들 이름을 터미널에 출력
    "listFiles": true, // 컴파일된 파일들 이름을 터미널에 출력
    "locale": "ko", // 에러메세지 출력 언어 설정
    "pretty": true, // 에러 메시지를 예쁘게 설정
    // @TODO 테스트 필요

    /////////// React ///////////
    "jsx": "react", // jsx 지원
    "jsxFactory": "React.createElement", // jsx 팩토리 함수 설정,

    /////////// JS ///////////
    // "allowJs": false, // 자바스크립트 파일 컴파일 허용 여부. 
    // "checkJs": false, // allowJs 옵션이 true여서 js파일 모듈을 사용시 js파일의 오류 검사 여부
    // "maxNodeModuleJsDepth": 0, // js 모듈을 검색할 최대 깊이

    /////////// Lint ///////////
    "strict": true, // 모든 엄격한 타입 검사 옵션을 활성화
    // noImplicitAny, noImplicitThis, alwaysStrict, strictNullChecks, strictFunctionTypes
    "allowUnreachableCode": false, // 도달 불가능한 코드에 대한 허용 여부.
    "allowUnusedLabels": false, // 사용하지 않는 라벨에 대한 허용 여부
    "noFallthroughCasesInSwitch": true, // 잘못 적혔다고 판단되는 switch문에 대한 에러 발생
    "noImplicitReturns": true, // 함수의 모든 경로가 값을 반환하지 않으면 에러 발생
    "suppressExcessPropertyErrors": false, // 객체 리터럴에 대한 초과 속성 검사 억제 여부
    "suppressImplicitAnyIndexErrors": false, // 인덱스 서명이없는 개체를 인덱싱하는 경우 --noImplicitAny 오류 억제여부
    // 자세한 내용은 문제 #1232를 참조
    "noStrictGenericChecks": true, // 함수에서 generic의 엄격한 검사 해제 여부
    "noUnusedLocals": true, // 사용안된 지역변수에 대한 오류 보고 여부
    "noUnusedParameters": true,  // 사용안된 파라미터에 대한 오류 보고 여부

    /////////// edit outfile ///////////
    "charset": "utf8", // 입력파일의 문자집합 형식
    "emitBOM": false,// 출력 파일의 시작 부분에 UTF-8 바이트 순서표 (BOM) 추가여부
    // "newLine": "lf", // end of line sequence 설정
    "removeComments": true, // 주석 삭제
    "disableSizeLimit": false, // Disable size limitation on JavaScript project.
    "noEmit": false, // 결과파일을 저장하지 않음
    "noEmitOnError": false, // 에러 발생시 결과파일을 저장하지 않음
    "preserveConstEnums": false, // const enum형 선언을 지우지 않을건지 여부

    /////////// more spec ///////////
    // "lib": [], // 컴파일에 포함될 라이브러리 파일 목록
    "downlevelIteration": false, // target이 ES3 및 ES5 일때도 for..of, spread, destructuring 문법 지원
    "experimentalDecorators": true, // ES Decorator에 대한 실험적 기능 사용 여부
    "stripInternal": false, // /** @ internal * /JSDoc annotation이 있는 코드에 대한 선언을 내 보내지 않을지 여부

    /////////// optimization ///////////
    "importHelpers": true, // tslib에서 helpers (e.g. __extends, __rest, etc..)를 가져온다.

    /////////// sourceMap ///////////
    // "inlineSourceMap": false, // 소스맵을 결과코드에 추가
    // @TODO 테스트 필요
    // "mapRoot": "./map", // "source map 파일을 저장할 root 디렉토리 지정
    // 지정하지 않으면 변환된 파일과 동일한 디렉토리에 저장된다.
    "sourceMap": true, // 소스맵(*.map) 파일 생성 여부
    // "sourceRoot": "", // 디버거가 알아야될 .ts파일 root 위치. 소스맵(*.map)에 적용된다.
    // @TODO 테스트 필요
    // "inlineSources": false, // 변환전 파일 .ts 코드를 결과코드에 추가
    // @TODO 테스트 필요

    /////////// etc ///////////

    // "noImplicitUseStrict": false, // @TODO 테스트 필요

    // "noLib": false, // 기본 라이브러리(lib.d.ts)를 가져오지 않는다.

    // "plugins": [ ], // 편집환경을 더 좋게 변경하기 위한 플러그인 기능

    // "preserveSymlinks": false, // Symlink파일에서 다른 모듈을 import시 기준경로를 Symlink 경로로 설정
    // 기존에는 Symlink파일에서 다른 모듈을 import시
    // Symlink파일의 실제 경로에서 모듈을 가져왔다.
    // https://nodejs.org/api/cli.html#cli_preserve_symlinks

    // "skipLibCheck": false, // 모든 선언파일(*.d.ts)의 유형검사를 건너뛸지 여부

    // "watch": false, // 파일 변경시 컴파일

    /////////// ??? ///////////
    // "isolatedModules": false, // @TODO 뭘까...
    // https://github.com/Microsoft/TypeScript/issues/2499
    // "emitDecoratorMetadata": false, // @TODO 테스트 필요
    // Emit design-type metadata for decorated declarations in source. See issue #2577 for details.
    // "noResolve": false // @TODO 테스트 필요
  }
}

디테일버전

{
    // https://github.com/Microsoft/TypeScript/tree/master/tests/cases/compiler
    // https://github.com/Microsoft/TypeScript/tree/master/tests/baselines/reference
    // 공식문서 외에도 위 테스트 코드를 참고시 도움이 됩니다.

    "compilerOptions": {
        "allowJs": false, // 자바스크립트 파일 컴파일 허용 여부. 
        // import add from './add.js' 와 같이 js파일 import 허용

        "allowSyntheticDefaultImports": false, // export default 를 export 한 값들을 가지는 객체로 설정
        // export class Foo { member: string; } 을 할시 (b.ts)
        // export default { Foo } 가 기본으로 설정된다.

        "allowUnreachableCode": false, // 도달 불가능한 코드에 대한 허용 여부.
        /* 
        function foo() {
            if (true) {
                return 42;
            }
            else {
                return "42"; // 도달 불가능
            }
        };
        */

        "allowUnusedLabels": false, // 사용하지 않는 라벨에 대한 허용 여부
        /*
        target1:
        target2: // 사용하지 않는 라벨
        while (true) {
            break target1;
        }
        */

        "alwaysStrict": false, // 항상 strict mode로 분석할지 여부
        // 모든 코드를 strict mode로 분석함
        // "use strict"; 를 컴파일된 js파일에 추가
        // @TODO noImplicitUseStrict 와 비교 필요

        "baseUrl": ".", // Non-relativ 모듈 혹은 paths 옵션의 기준 디렉토리

        "charset": "utf8", // 입력파일의 문자집합 형식

        "checkJs": false, // allowJs 옵션이 true여서 js파일 모듈을 사용시 js파일의 오류 검사 여부

        "declaration": false, // .d.ts 파일의 생성 여부

        "declarationDir": "", // .d.ts 파일이 생성되는 디렉토리 설정

        "diagnostics": false, // @TODO 테스트 필요
        // Show diagnostic information.

        "disableSizeLimit": false, // @TODO 테스트 필요
        // Disable size limitation on JavaScript project.

        "downlevelIteration": false, // target이 ES3 및 ES5 일때도 for..of, spread, destructuring 문법 지원
        // TypeScript 2.3 이전에는 target이 ES6/ES2015 이후 버전일때만 지원함

        "emitBOM": false,// 출력 파일의 시작 부분에 UTF-8 바이트 순서표 (BOM) 추가여부
        // 윈도우 스토어 인증을 통과하기 위해 필요
        // https://stackoverflow.com/questions/33722915/typescript-generated-js-files-encoding

        "emitDecoratorMetadata": false, // @TODO 테스트 필요
        // Emit design-type metadata for decorated declarations in source. See issue #2577 for details.

        "experimentalDecorators": false, // ES Decorator에 대한 실험적 기능 사용 여부
        // vue에서는 vue와 Typescript를 같이 쓸때는 활성화를 권장하고 있다.

        "forceConsistentCasingInFileNames": false, // 파일명에 대소문자 구분하지 않아도 되는 기능 사용 여부
        // 직역: 파일 이름에 일관된 casing 강제 적용

        "importHelpers": false, // tslib에서 helpers (e.g. __extends, __rest, etc..)를 가져온다.
        // 중복코드를 없애기 위한 최적화용 옵션
        // https://github.com/Microsoft/tslib

        "inlineSourceMap": false, // 소스맵을 결과코드에 추가
        // @TODO 테스트 필요

        "inlineSources": false, // 변환전 파일 .ts 코드를 결과코드에 추가
        // @TODO 테스트 필요

        "isolatedModules": false, // @TODO 뭘까...
        // https://github.com/Microsoft/TypeScript/issues/2499

        "jsx": false, // jsx 지원

        "jsxFactory": "React.createElement", // jsx 팩토리 함수 설정,

        "lib": [], // 컴파일에 포함될 라이브러리 파일 목록
        // target 옵션 값에 따라 기본으로 포함되는 라이브러리가 있다.
        // lib 옵션 설정시 그 라이브러리 파일만 포함된다.
        // target ES5 -> DOM,ES5,ScriptHost
        // target ES6 -> DOM,ES6,DOM.Iterable,ScriptHost
        /*
        ES5 
        ES6 
        ES2015 
        ES7 
        ES2016 
        ES2017 
        ESNext 
        DOM 
        DOM.Iterable 
        WebWorker 
        ScriptHost 
        ES2015.Core 
        ES2015.Collection 
        ES2015.Generator 
        ES2015.Iterable 
        ES2015.Promise 
        ES2015.Proxy 
        ES2015.Reflect 
        ES2015.Symbol 
        ES2015.Symbol.WellKnown 
        ES2016.Array.Include 
        ES2017.object 
        ES2017.SharedMemory 
        ES2017.TypedArrays 
        esnext.asynciterable 
        */

        "listEmittedFiles": false, // 컴파일된 결과 파일들 이름을 터미널에 출력

        "listFiles": false, // 컴파일된 파일들 이름을 터미널에 출력

        "locale": "ko", // 에러메세지 출력 언어 설정

        "mapRoot": "", // "source map 파일을 저장할 root 디렉토리 지정
        // 지정하지 않으면 변환된 파일과 동일한 디렉토리에 저장된다.

        "maxNodeModuleJsDepth": 0, // js 모듈을 검색할 최대 깊이
        // allowJs 옵션이 활성화 되있을때만 적용
        // https://github.com/Microsoft/TypeScript/tree/master/tests/cases/projects/NodeModulesSearch/maxDepthIncreased

        "module": "es3", // 모듈 설정
        // "AMD", "System" 사용시 outFile 옵션을 설정하면 여러개의 모듈이 포함된 단일파일로 출력
        // "ES6", "ES2015"는 target값이 "ES5" 이하일때 사용 가능

        "moduleResolution": "node", // 모듈 (검색)해석 방식 설정

        "newLine": "lf", // end of line sequence 설정
        // 기본적으로 플랫폼에 따라 "crlf" (windows) or "lf" (unix) 가 설정됨

        "noEmit": false, // 결과파일을 저장하지 않음
        // @TODO 테스트 필요

        "noEmitHelpers": false, // helpers (e.g. __extends, __rest, etc..)를 결과파일에 포함시키지 않음
        // https://github.com/ngParty/ts-helpers
        // 이 옵션 대신 importHelpers 옵션을 사용시 더 깔끔하게 최적화 가능

        "noEmitOnError": false, // 에러 발생시 결과파일을 저장하지 않음

        "noFallthroughCasesInSwitch": false, // 잘못 적혔다고 판단되는 switch문에 대한 에러 발생
        // 예를 들어 case문에 break가 없으면 오류 발생

        "noImplicitAny": false, // any타입 금지

        "noImplicitReturns": false, // 함수의 모든 경로가 값을 반환하지 않으면 에러 발생

        "noImplicitThis": false, // this 타입을 명시적으로 지정하지 않으면 에러 발생

        "noImplicitUseStrict": false, // @TODO 테스트 필요

        "noLib": false, // 기본 라이브러리(lib.d.ts)를 가져오지 않는다.
        // @TODO 옵션 사용처

        "noResolve": false, // @TODO 테스트 필요

        "noStrictGenericChecks": false, // 함수에서 generic의 엄격한 검사 해제 여부
        /*
        type A = <T, U>(x: T, y: U) => [T, U];
        type B = <S>(x: S, y: S) => [S, S];

        function f(a: A, b: B) {
            a = b;  // 엄격한 검사시 Error
            b = a;  // Ok
        }
        */

        "noUnusedLocals": false, // 사용안된 지역변수에 대한 오류 보고 여부

        "noUnusedParameters": false,  // 사용안된 파라미터에 대한 오류 보고 여부

        "outDir": "", // 출력할 디덱토리
        // @TODO 테스트 필요

        "outFile": "", // 단일파일로 출력시 파일명
        // @TODO 테스트 필요

        "paths": { }, // baseUrl 옵션을 기준디렉토리로 불러올 모듈의 위치 설정이 가능
        // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping

        "plugins": [ ], // 편집환경을 더 좋게 변경하기 위한 플러그인 기능
        // 새로운 구문이나 다른 형식 검사 동작등 새로운 언어 기능을 추가할수는 없음
        // https://github.com/Microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin

        "preserveConstEnums": false, // const enum형 선언을 지우지 않을건지 여부
        // 본래 컴파일 하는동안 완전히 제거되어 성능과 메모리상 이점을 얻기위해
        // const enum형 선언은 지우고 코드상에 직접 맵핑되는데 이 옵션을 활성화시
        // const enum형 선언을 지우지 않는다
        /*
        // js파일
        const enum E {
            Value = 1, Value2 = Value
        }
        console.log(E.value)
        console.log(E.value2)

        // 비활성화시 결과파일
        console.log(1 /* Value * /);
        console.log(1 /* Value2 * /);


        // 활성화시 결과파일
        var E;
        (function (E) {
            E[E["Value"] = 1] = "Value";
            E[E["Value2"] = 1] = "Value2";
        })(E || (E = {}));

        console.log(E.value)
        console.log(E.value2)
        */

        "preserveSymlinks": false, // Symlink파일에서 다른 모듈을 import시 기준경로를 Symlink 경로로 설정
        // 기존에는 Symlink파일에서 다른 모듈을 import시
        // Symlink파일의 실제 경로에서 모듈을 가져왔다.
        // https://nodejs.org/api/cli.html#cli_preserve_symlinks

        "pretty": false, // 에러 메시지를 예쁘게 설정
        // @TODO 테스트 필요

        "reactNamespace": "", // React 네임스페이스 설정. 권장되지 않는 옵션.
        // jsxFactory 옵션을 사용하십시오

        "removeComments": false, // 주석 삭제
        // @TODO '/*!' 주석 테스트 필요

        "rootDir": "", // 입력파일의 rootDir 설정
        // outDir옵션을 사용할때만 사용

        "rootDirs": [ ], // 가상 디덱토리를 설정
        // https://www.typescriptlang.org/docs/handbook/module-resolution.html#virtual-directories-with-rootdirs

        "skipDefaultLibCheck": false, // 사용을 권장하지 않음 skipLibCheck 옵션을 사용

        "skipLibCheck": false, // 모든 선언파일(*.d.ts)의 유형검사를 건너뛸지 여부

        "sourceMap": false, // 소스맵(*.map) 파일 생성 여부

        "sourceRoot": "", // 디버거가 알아야될 .ts파일 root 위치. 소스맵(*.map)에 적용된다.
        // @TODO 테스트 필요

        "strict": false, // 모든 엄격한 타입 검사 옵션을 활성화
        // noImplicitAny, noImplicitThis, alwaysStrict, strictNullChecks, strictFunctionTypes

        "strictFunctionTypes": false, //@TODO 테스트 필요

        "strictNullChecks": false, // null과 undefined 타입 구분 여부
        // https://basarat.gitbooks.io/typescript/docs/options/strictNullChecks.html

        "stripInternal": false, // /** @ internal * /JSDoc annotation이 있는 코드에 대한 선언을 내 보내지 않을지 여부
        // @TODO 부가설명 필요

        "suppressExcessPropertyErrors": false, // 객체 리터럴에 대한 초과 속성 검사 억제 여부
        // @TODO 부가설명 필요

        "suppressImplicitAnyIndexErrors": false, // 인덱스 서명이없는 개체를 인덱싱하는 경우 --noImplicitAny 오류 억제여부
        // 자세한 내용은 문제 #1232를 참조
        // @TODO 부가설명 필요

        "target": "es3", // 코드에서 사용할 ECMAScript 버전 설정

        "traceResolution": false, // 모듈 검색에 대한 로그메세지 출력 여부

        "typeRoots": [ ], // 타입(*.d.ts)파일을 가져올 디렉토리 설정
        // 설정 안할시 기본적으로 ./node_modules/@types

        "types": [ ], // 타입을 가져올 패키지목록 (따른 패키지는 (*.d.ts)파일을 가져오지 않음)
        // ["node", "lodash", "express"] 설정시
        // ./node_modules/@types/node, ./node_modules/@types/lodash, ./node_modules/@types/express
        // 위 3개를 가져오고 node_modules/@types/* 의 다른 패키지는 가져오지 않음

        "watch": false // 파일 변경시 컴파일
    }
}

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

enum을 사용하는 이유  (0) 2020.02.03
TypeScript 핸드북 1 - 기본 타입  (0) 2019.04.24
interface와 class의 상속관계 증명  (0) 2019.02.07
[typescript]decorator  (0) 2018.12.11
[typescript]iterator  (0) 2018.12.11

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

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

+ Recent posts