Arrays변수에 대한 타입 주석함수에서 입출력 타입 선언(Type Annotation)익명 함수오브젝트 타입Optional PropertiesUnion TypeType AliasesInterfacesType Aliases 🆚 InterfacesType AssertionLiteral Types 사용예시 — 허용 가능한 값을 명시하는 용도로 사용가능함null and undefinedNon-null Assertion Operator (Postfix !)EnumReverse mappingsiterate
Arrays
- number[] , string[] 같은 형태로 작성함
- number[] ↔ Array<number>
변수에 대한 타입 주석
let myname: string = "Alice"; // No type annotation needed -- 'myName' inferred as type 'string' let myName = "Alice";
- 대부분의 경우에는 타입스크립트에서 알아서 타입을 추론해줌
함수에서 입출력 타입 선언(Type Annotation)
function greet(name: string) { console.log("Hello, " + name.toUpperCase() + "!!"); }
- parameter에 대한 type annotation이 되어 있지 않더라도 TypeScript에서 파라미터 갯수는 체크함
function getFavoriteNumber(): number { return 26; }
- return 문 기반으로 함수의 반환 타입을 알아서 추론해줌
- Return type 붙이는건 documentation, 혹은 명시적으로 표기하기 위함임
익명 함수
- 익명 함수가 TypeScript가 어떻게 호출되는지를 결정할 수 있는 곳에서 정의된다면, 해당 함수의 파라미터는 자동으로 타입이 주어짐
// No type annotations here, but TypeScript can spot the bug const names = ["Alice", "Bob", "Eve"]; // Contextual typing for function names.forEach(function (s) { console.log(s.toUppercase()); Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'? });
오브젝트 타입
// The parameter's type annotation is an object type function printCoord(pt: { x: number; y: number }) { console.log("The coordinate's x value is " + pt.x); console.log("The coordinate's y value is " + pt.y); } printCoord({ x: 3, y: 7 });
Optional Properties
- object type에서 property가 optional이라는 것을 명시하기 위해서는
?
를 property name에 붙이면 됨
function printName(obj: { first: string; last?: string }) { // ... } // Both OK printName({ first: "Bob" }); printName({ first: "Alice", last: "Alisson" });
- JavaScript에서는 존재하지 않는 값에 접근하면 Runtime error가 아닌
undefined
값을 얻기 때문에 그 값을 이용하기 위해서는 그 전에 check 하는 과정이 필요함
function printName(obj: { first: string; last?: string }) { // Error - might crash if 'obj.last' wasn't provided! console.log(obj.last.toUpperCase()); Object is possibly 'undefined'. if (obj.last !== undefined) { // OK console.log(obj.last.toUpperCase()); } // A safe alternative using modern JavaScript syntax: console.log(obj.last?.toUpperCase()); }
?
연산자를 이용하여 값이 있을때에만 작동하게 작성 가능함
Union Type
- 값이 여러 타입 중 하나 임을 명시하고 싶을 때 Union Type을 사용함
function printId(id: number | string) { console.log("Your ID is: " + id); } // OK printId(101); // OK printId("202"); // Error printId({ myID: 22342 }); Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.
- Union Type들의 모든 타입에 대해서 가능한 로직을 함수 내부에 작성해야함
Type Aliases
- Type 선언을 계속해서 재활용하고 싶을 때 type에 name을 붙여서 활용하게 하는 것임
- type에 name을부여하고 싶을 때 사용
type Point = { x: number; y: number; }; // Exactly the same as the earlier example function printCoord(pt: Point) { console.log("The coordinate's x value is " + pt.x); console.log("The coordinate's y value is " + pt.y); } printCoord({ x: 100, y: 100 }); type ID = number | string;
Interfaces
- object type에 이름을 붙일 수 있는 또다른 방법
interface Point { x: number; y: number; } function printCoord(pt: Point) { console.log("The coordinate's x value is " + pt.x); console.log("The coordinate's y value is " + pt.y); } printCoord({ x: 100, y: 100 });
Type Aliases 🆚 Interfaces
- 둘은 되게 비슷해서 둘 중에 자유롭게 선택해서 사용하면 됨
- 두 개 사이의 뚜렷한 차이는 type은 새 property를 추가하기 위해 새롭게 정의될 수 없는데 interface는 그것이 언제나 가능함
// Extending an interface interface Animal { name: string } interface Bear extends Animal { honey: boolean } const bear = getBear() bear.name bear.honey ///// // Adding new fields to an // existing interface interface Window { title: string } interface Window { ts: TypeScriptAPI } const src = 'const a = "Hello World"'; window.ts.transpileModule(src, {});
// Extending a type via intersections type Animal = { name: string } type Bear = Animal & { honey: boolean } const bear = getBear(); bear.name; bear.honey; // A type cannot be changed // after being created type Window = { title: string } type Window = { ts: TypeScriptAPI } // Error: Duplicate identifier 'W
Type Assertion
- TypeScript 가 모르는 정보를 우리가 더 알고 있을 수도 있음
- 예를 들어
document.getElementById
에서 반환되는 타입이 TypeScript 는HTMLElement
의 종류 라고만 알고 있는데, 내가 짠 코드에서는HTMLCanvasElement
만 반환한다는 것을 알고 있을 때, Type Assertion을 쓸 수 있음
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
- TypeScript는 type을 조금 더 상세한 또는 조금 덜 상세한 타입으로 바꾸는 것만 허용함. 예를 들어 string 을 number로 바꾸는 건 에러를 띄움
const x = "hello" as number; Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Literal Types
- type이 구체적인
string
과number
를 가리키도록 할 수 있음
let changingString = "Hello World"; changingString = "Olá Mundo"; // Because `changingString` can represent any possible string, that // is how TypeScript describes it in the type system changingString; /* let changingString: string */ const constantString = "Hello World"; // Because `constantString` can only represent 1 possible string, it // has a literal type representation constantString; /* const constantString: "Hello World" */
- const로 선언한 constantString의 타입은
“Hello World”
임 string이 아니라
사용예시 — 허용 가능한 값을 명시하는 용도로 사용가능함
let x: "hello" = "hello"; // OK x = "hello"; // ... x = "howdy"; Type '"howdy"' is not assignable to type '"hello"'.
function printText(s: string, alignment: "left" | "right" | "center") { // ... } printText("Hello, world", "left"); printText("G'day, mate", "centre"); Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.
function compare(a: string, b: string): -1 | 0 | 1 { return a === b ? 0 : a > b ? 1 : -1; }
null
and undefined
Non-null Assertion Operator (Postfix !
)
- 변수 뒤에
!
를 붙이면 해당 변수는null
이나undefined
가 아니라고 명시적으로 말해주는 것임
undefined 체크
- if (변수 === undefined) { … }
Enum
Reverse mappings
In addition to creating an object with property names for members, numeric enums members also get a reverse mapping from enum values to enum names. For example, in this example:
enum Enum { A, } let a = Enum.A; let nameOfA = Enum[a]; // "A" Try