(원문) http://www.typescriptlang.org/Handbook
[Basic Types]
변수 마다 명시적 type 지정을 한다.
var isDone: boolean = false;
array도 마찬가지이고 generic 선언 형식도 지원한다.
var list:number[] = [1, 2, 3];
var list:Array<number> = [1, 2, 3];
enum type도 지원
enum Color {Red = 1, Green, Blue}; var c: Color = Color.Green;
enum Color {Red = 1, Green, Blue}; var colorName: string = Color[2]; alert(colorName);
Any는 뭐 기본이니 TypeScript에서 배열에 이것저것 넣을 때 유용할 거 같다.
var notSure: any = 4; notSure = "maybe a string instead"; notSure = false; // okay, definitely a boolean
var list:any[] = [1, true, "free"]; list[1] = 100;
void도 있음.
function warnUser(): void { alert("This is my warning message"); }
[Interfaces]
기본적인 interface 문법이다.class 선언하듯 property를 정해서 interface로 선언하고 사용하면 된다.
interface LabelledValue { label: string; } function printLabel(labelledObj: LabelledValue) { console.log(labelledObj.label); } var myObj = {size: 10, label: "Size 10 Object"}; printLabel(myObj);
그리고 interface를 사용하되 property 속성을 '?' keyword를 사용하여 optional로 처리 하여 사용하는 class가 사용하지 않게 할 수 있음.
interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig): {color: string; area: number} { var newSquare = {color: "white", area: 100}; if (config.color) { newSquare.color = config.color; } if (config.width) { newSquare.area = config.width * config.width; } return newSquare; } var mySquare = createSquare({color: "black"});
type checking 상황에서 Interface를 사용하게 될 경우 실수로 인한 오타의 경우 (ex config.collor) 확인가능하다. 일반적인 javascript 상황에서는 config의 속성으로 인지하고 null값의 변수로 처리되는것에 반해...
[Function Types]
function을 정의하는데 interface를 사용한다....
좀 이상하긴 한데.. 굳이 보자면 static function 정도로 봐야 할까?
interface SearchFunc { (source: string, subString: string): boolean; }
var mySearch: SearchFunc; mySearch = function(source: string, subString: string) { var result = source.search(subString); if (result == -1) { return false; } else { return true; } }
[Array Types]
Array도 interface를 사용해서 선언 할 수 있음.
다만 index는 number, string만 가능하다.
interface StringArray { [index: number]: string; } var myArray: StringArray; myArray = ["Bob", "Fred"];
이건 뭐...?
interface Dictionary { [index: string]: string; length: number; // error, the type of 'length' is not a subtype of the indexer }
[Class Types]
Interface를 선언하고 그것을 implements 해서 class를 선언
interface ClockInterface { currentTime: Date; setTime(d: Date); } class Clock implements ClockInterface { currentTime: Date; setTime(d: Date) { this.currentTime = d; } constructor(h: number, m: number) { } }
class와 interface를 사용할 때 static side, instance side의 개념을 이해해야 함.
아래 예제의 interface에서 선언된 constructor(new)는 static side에서 선언되어 있어 class의 instance side에서 new가 선언되어 있지 않는 것으로 판단되어 에러로 처리된다.
interface ClockInterface { new (hour: number, minute: number); } class Clock implements ClockInterface { currentTime: Date; constructor(h: number, m: number) { } }
그래서 아래와 같이 interface를 구현하지 말고 class 선언 하고 interface type으로 interface의 instance(엄밀히보면 아닐 듯)를 만들고 다시 instance를 생성자를 호출해서 만들며 초기화 한다..(맞나??)
좀 복잡하다.. 사실 상 interface로 생성자를 명시할 필요는 있겠지만.. 생각보다 복잡하네..
interface ClockStatic { new (hour: number, minute: number); } class Clock { currentTime: Date; constructor(h: number, m: number) { } } var cs: ClockStatic = Clock; var newClock = new cs(7, 30);
[Extending Interfaces]
interface 간 상속이 가능하다. 다중상속도 가능하다.
interface Shape { color: string; } interface Square extends Shape { sideLength: number; } var square: Square; square.color = "blue"; square.sideLength = 10;
[Hybrid Types]
위에서 언급함 interface의 속성들이 함께 사용 될 수 있음.
interface Counter { (start: number): string; interval: number; reset(): void; } var c: Counter; c(10); c.reset(); c.interval = 5.0;
[Classes]
간단한 class 예제
class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; } } var greeter = new Greeter("world");
아래는 컴파일 된 JavaScript 결과물임.
var Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
var greeter = new Greeter("world");
[Inheritance]
아래에서 sam은 type을 선언하지 않고 바로 Snake의 instance를 생성하고 tom은 Animal type으로 Horse의 instance를 생성했음. 결과적으로는 각 class들(Snake, Horse)에서 override한 move()이 호출 된다.
JavaScript의 속성상 move()의 prototype이 다르더라도 Animal의 move()가 각 class에서 override 되어 tom의 type이 Animal이라도 instance에서 override된 move()가 호출 되었음.
class Animal { name:string; constructor(theName: string) { this.name = theName; } move(meters: number) { alert(this.name + " moved " + meters + "m."); } } class Snake extends Animal { constructor(name: string) { super(name); } move() { alert("Slithering..."); super.move(5); } } class Horse extends Animal { constructor(name: string) { super(name); } move() { alert("Galloping..."); super.move(45); } } var sam = new Snake("Sammy the Python"); var tom: Animal = new Horse("Tommy the Palomino"); sam.move(); tom.move(34);
[Private/Public modifiers]
기본적으로 class내의 properties, methods들은 public 속성을 가지고 private으로 선언하고자 할 경우 모든 variables, methods에 명시적으로 private을 선언해야 한다.
[Parameter properties]
private 키워드를 생성자의 argument에 선언하면 실제 class의 property를 argument로 초기화 한다는 얘기, public property도 마찬가지.
class Animal { constructor(private name: string) { } move(meters: number) { alert(this.name + " moved " + meters + "m."); } }
[Accessors]
setter, getter를 위해 set, get 지시자를 사용하면 된다.
다만 compiler output을 ECMAScript 5로 설정해야지 사용 가능하다고 함.
다만 compiler output을 ECMAScript 5로 설정해야지 사용 가능하다고 함.
ar passcode = "secret passcode"; class Employee { private _fullName: string; get fullName(): string { return this._fullName; } set fullName(newName: string) { if (passcode && passcode == "secret passcode") { this._fullName = newName; } else { alert("Error: Unauthorized update of employee!"); } } } var employee = new Employee(); employee.fullName = "Bob Smith"; if (employee.fullName) { alert(employee.fullName); }
[Static Properties]
static properties도 사용 가능함.. 일반적임.
class Grid { static origin = {x: 0, y: 0}; calculateDistanceFromOrigin(point: {x: number; y: number;}) { var xDist = (point.x - Grid.origin.x); var yDist = (point.y - Grid.origin.y); return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale; } constructor (public scale: number) { } } var grid1 = new Grid(1.0); // 1x scale var grid2 = new Grid(5.0); // 5x scale alert(grid1.calculateDistanceFromOrigin({x: 10, y: 10})); alert(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
[Constructor functions]
좀 이상한 예제긴 하지만 greeterMaker에 Greeter 원형을 대입해서 static property를 수정할 수 있는 것을 볼 수 있음.
class Greeter { static standardGreeting = "Hello, there"; greeting: string; greet() { if (this.greeting) { return "Hello, " + this.greeting; } else { return Greeter.standardGreeting; } } } var greeter1: Greeter; greeter1 = new Greeter(); alert(greeter1.greet()); var greeterMaker: typeof Greeter = Greeter; greeterMaker.standardGreeting = "Hey there!"; var greeter2:Greeter = new greeterMaker(); alert(greeter2.greet());
[Using a class as an interface]
class도 interface로 사용할 수 있음.. 근대 왜?
class Point { x: number; y: number; } interface Point3d extends Point { z: number; } var point3d: Point3d = {x: 1, y: 2, z: 3};
댓글 없음:
댓글 쓰기