├── package.json ├── 11_utility_type ├── 8_non_nullable_type.ts ├── 7_extract_type.ts ├── 6_exclude_type.ts ├── 11_return_type.ts ├── 9_parameter_type.ts ├── 2_required_type.ts ├── 10_constructor_parameter.ts ├── 5_omit_type.ts ├── 3_readonly_type.ts ├── 4_pick_type.ts ├── 12_template_literal.ts └── 1_partial_type.ts ├── 1_basic ├── 1_problem_with_js.ts ├── 1_problem_with_js.js ├── 6_casting.ts ├── 3_type_and_interface.ts ├── 5_type_inference.ts ├── 2_basics.js ├── 2_basics.ts └── 4_enum.ts ├── .idea ├── vcs.xml ├── misc.xml ├── .gitignore ├── modules.xml └── actual.iml ├── 6_array ├── 2_spread_operator.ts ├── 3_multi_dimension_array.ts └── 1_problems_with_array_in_js.ts ├── 15_import_and_export ├── 2_import_2.ts ├── 1_import_default_2.ts ├── 1_export_default_1.ts ├── 2_export_1.ts └── 3_multiple_ways_to_import_and_export.ts ├── 8_object ├── 2_property_check.ts ├── 1_defining_object.ts ├── 4_optional_and_undefined_property.ts ├── 6_object_intersection.ts ├── 3_nested_object.ts ├── 5_object_union.ts └── 7_key_value_mapping.ts ├── 9_class ├── 2_readonly_property.ts ├── 4_class_as_type_and_value.ts ├── 8_abstract_class.ts ├── 1_defining_class.ts ├── 3_property_initialization.ts ├── 9_visibility_keyword.ts ├── 6_inheritance.ts ├── 7_override.ts └── 5_interface.ts ├── 12_experimental_decorator ├── 4_property_decorator.ts ├── 5_parameter_decorator.ts ├── 3_accessor_decrator.ts ├── 1_class_decorator.ts └── 2_method_decorator.ts ├── 5_any_unknown_never ├── 3_never_type.ts ├── 1_loop_holes_of_any.ts └── 2_unknown_type.ts ├── 10_generic ├── 2_generic_in_interface.ts ├── 3_generic_in_type.ts ├── 8_generic_in_promise.ts ├── 7_generic_in_implementation.ts ├── 4_generic_in_class.ts ├── 6_generic_in_method.ts ├── 1_generic_in_function.ts └── 5_generic_in_inheritance.ts ├── 2_union_and_intersection ├── 2_intersection_basics.ts ├── 1_union_basics.ts └── 3_narrowing.ts ├── 3_function ├── 2_function_type.ts ├── 3_overloading.ts ├── 5_type_predicate.ts ├── 4_statement_and_expression.ts └── 1_defining_function.ts ├── 16_extras └── 1_infer_keyword.ts ├── 14_namespace └── 1_namespace.ts ├── 7_tuple └── 1_what_is_tuple.ts ├── 13_reflection ├── 1_reflection_metadata.ts └── 2_reflection_and_decorator.ts ├── 4_type_and_interface ├── 1_type_vs_interface.ts └── 2_extension.ts └── tsconfig.json /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "reflect-metadata": "^0.1.13" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /11_utility_type/8_non_nullable_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Non Nullable type 3 | */ 4 | type NonNull = NonNullable; -------------------------------------------------------------------------------- /11_utility_type/7_extract_type.ts: -------------------------------------------------------------------------------- 1 | type stringOnly = Extract; 2 | 3 | type functionOnly = Extract void), Function>; -------------------------------------------------------------------------------- /1_basic/1_problem_with_js.ts: -------------------------------------------------------------------------------- 1 | function add(num1: number, num2: number){ 2 | return num1 + num2; 3 | } 4 | 5 | console.log(add(1, 2)); 6 | console.log(add(1, '2')); -------------------------------------------------------------------------------- /1_basic/1_problem_with_js.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function add(num1, num2) { 3 | return num1 + num2; 4 | } 5 | console.log(add(1, 2)); 6 | console.log(add(1, '2')); 7 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /11_utility_type/6_exclude_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Exclude Type 3 | */ 4 | 5 | type NoString = Exclude; 6 | 7 | type NoFunction = Exclude void), Function>; -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /11_utility_type/11_return_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Return Type 3 | */ 4 | type ReturnTypeSample = ReturnType<()=> number>; 5 | 6 | type FunctionSign = (x: number, y: number) => number; 7 | 8 | type ReturnType2 = ReturnType; -------------------------------------------------------------------------------- /11_utility_type/9_parameter_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Parameter Type 3 | */ 4 | 5 | function sampleFunction(x: number, y: string, z: boolean){ 6 | 7 | } 8 | 9 | type Params = Parameters; 10 | type Params2 = Parameters<(one: number) => void>; -------------------------------------------------------------------------------- /11_utility_type/2_required_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Required Type 3 | */ 4 | interface Dog { 5 | name: string; 6 | age?: number; 7 | country?: string; 8 | } 9 | 10 | const requiredDog: Required = { 11 | name: '모찌', 12 | age: 7, 13 | country: '한국' 14 | } -------------------------------------------------------------------------------- /6_array/2_spread_operator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Spread Operator 3 | */ 4 | const onlyString = ['1', '2', '3', '4']; 5 | const onlyNumbers = [1, 2, 3, 4]; 6 | 7 | const arr1 = [ 8 | ...onlyString, 9 | ]; 10 | 11 | const arr2 = [ 12 | ...onlyString, 13 | ...onlyNumbers, 14 | ] -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /15_import_and_export/2_import_2.ts: -------------------------------------------------------------------------------- 1 | import {IdolModel, rose, number, ICat} from './2_export_1'; 2 | 3 | const iu = new IdolModel('아이유', 32); 4 | console.log(iu); 5 | console.log(rose); 6 | console.log(number); 7 | 8 | const cat: ICat = { 9 | name: '냥냥이', 10 | age: 12, 11 | } 12 | console.log(cat); -------------------------------------------------------------------------------- /8_object/2_property_check.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Property Check 3 | * 4 | * 초과 속성 검사 5 | */ 6 | type TName = { 7 | name: string; 8 | } 9 | 10 | type TAge = { 11 | age: number; 12 | } 13 | 14 | const iu = { 15 | name: '아이유', 16 | age: 30, 17 | } 18 | 19 | const testName: TName = iu; 20 | const testAge: TAge = iu; -------------------------------------------------------------------------------- /11_utility_type/10_constructor_parameter.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Constructor Parameter 3 | */ 4 | class Idol { 5 | name: string; 6 | age: number; 7 | 8 | constructor(name: string, age: number) { 9 | this.name = name; 10 | this.age = age; 11 | } 12 | } 13 | 14 | type ConstructorParamType = ConstructorParameters; -------------------------------------------------------------------------------- /9_class/2_readonly_property.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * readonly 프로퍼티 3 | */ 4 | class Idol { 5 | readonly name: string; 6 | age: number; 7 | 8 | constructor(name: string, age: number){ 9 | this.name = name; 10 | this.age = age; 11 | } 12 | } 13 | 14 | const yuJin = new Idol('안유진', 23); 15 | 16 | yuJin.age = 32; 17 | // yuJin.name = '코드팩토리'; -------------------------------------------------------------------------------- /.idea/actual.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /11_utility_type/5_omit_type.ts: -------------------------------------------------------------------------------- 1 | interface Post { 2 | title: string; 3 | content: string; 4 | createdAt: Date; 5 | } 6 | 7 | function createPost(post: Omit): Post { 8 | return { 9 | ...post, 10 | createdAt: new Date(), 11 | }; 12 | } 13 | 14 | createPost({ 15 | title: '요즘 개발자 취업 어떤가요?', 16 | content: '나이 30 넘어서도 해볼만한가요?', 17 | }); -------------------------------------------------------------------------------- /11_utility_type/3_readonly_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Readonly Type 3 | */ 4 | interface Cat { 5 | name: string; 6 | age: number; 7 | } 8 | 9 | const nyaong: Cat = { 10 | name: '냐옹이', 11 | age: 8 12 | }; 13 | 14 | nyaong.name = '코드팩토리'; 15 | 16 | const bori: Readonly = { 17 | name: '보리', 18 | age: 7, 19 | } 20 | 21 | // bori.name = '아이유'; 22 | 23 | Object.freeze(bori); -------------------------------------------------------------------------------- /12_experimental_decorator/4_property_decorator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Property Decorator 3 | */ 4 | class UserModel{ 5 | @PropertyLogger 6 | id: string; 7 | name: string; 8 | 9 | constructor(id: string, name: string){ 10 | this.id = id; 11 | this.name = name; 12 | } 13 | } 14 | 15 | function PropertyLogger(target: any, propertyKey: string){ 16 | console.log(`${propertyKey} 값이 정의 됐습니다.`) 17 | } -------------------------------------------------------------------------------- /11_utility_type/4_pick_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Pick Type 3 | */ 4 | interface Post { 5 | title: string; 6 | content: string; 7 | createdAt: Date; 8 | } 9 | 10 | function createPost(post: Pick): Post { 11 | return { 12 | ...post, 13 | createdAt: new Date(), 14 | }; 15 | } 16 | 17 | createPost({ 18 | title: '요즘 개발자 취업 어떤가요?', 19 | content: '나이 30 넘어서도 해볼만한가요?', 20 | }); -------------------------------------------------------------------------------- /11_utility_type/12_template_literal.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Template Literal 3 | */ 4 | type CodeFactory = 'Code Factory'; 5 | 6 | // Uppercase 7 | type CodeFactoryUpper = Uppercase; 8 | 9 | // Lowercase 10 | type CodeFactoryLower = Lowercase; 11 | 12 | // Capitalize 13 | type CodeFactoryCapital = Capitalize; 14 | 15 | // Uncapitalize 16 | type CodeFactoryUnCapital = Uncapitalize; -------------------------------------------------------------------------------- /5_any_unknown_never/3_never_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Never Type 3 | */ 4 | // (1) 함수에서 에러를 던질때 5 | function throwError() : never{ 6 | throw Error(); 7 | } 8 | 9 | // (2) 무한 룹 10 | function infiniteLoop(): never{ 11 | while(true){ 12 | 13 | } 14 | } 15 | 16 | // (3) 존재 할 수 없는 인터섹션 17 | type StringAndNumber = string & number; 18 | 19 | // let neverType: never = 10; 20 | // let neverType: never = undefined; 21 | // let neverType: never = null; -------------------------------------------------------------------------------- /15_import_and_export/1_import_default_2.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * ./ 3 | * ../14_namespace 4 | */ 5 | import Example from './1_export_default_1'; 6 | 7 | // const iu = new IdolModel('아이유', 23); 8 | // console.log(iu); 9 | 10 | // console.log(IdolModel); 11 | 12 | // const cat: IdolModel = { 13 | // name: '냥냥이', 14 | // breed: '스코티시폴드', 15 | // }; 16 | 17 | const yuJin = new Example.IdolModel('안유진', 23); 18 | 19 | console.log(yuJin); 20 | console.log(Example.number); -------------------------------------------------------------------------------- /8_object/1_defining_object.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Object 3 | */ 4 | const codefactory = { 5 | name: '코드팩토리', 6 | age: 32, 7 | } 8 | 9 | interface IPerson{ 10 | name: string; 11 | age: number; 12 | } 13 | 14 | type TPerson = { 15 | name: string; 16 | age: number; 17 | } 18 | 19 | const iPerson: IPerson = { 20 | name: '아이유', 21 | age: 30, 22 | } 23 | 24 | const tPerson: TPerson = { 25 | name: '유인나', 26 | age: 30, 27 | } 28 | 29 | iPerson.name; 30 | tPerson.age; -------------------------------------------------------------------------------- /15_import_and_export/1_export_default_1.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Export 3 | */ 4 | // export default 5 | class IdolModel{ 6 | name: string; 7 | age: number; 8 | 9 | constructor(name: string, age: number){ 10 | this.name = name; 11 | this.age = age; 12 | } 13 | } 14 | 15 | const number = 12; 16 | 17 | // export default number; 18 | 19 | interface ICat{ 20 | name: string; 21 | breed: string; 22 | } 23 | 24 | export default { 25 | IdolModel, 26 | number, 27 | } -------------------------------------------------------------------------------- /15_import_and_export/2_export_1.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Export 3 | */ 4 | export class IdolModel { 5 | name: string; 6 | age: number; 7 | 8 | constructor(name: string, age: number) { 9 | this.name = name; 10 | this.age = age; 11 | } 12 | } 13 | 14 | export const rose = new IdolModel('로제', 28); 15 | 16 | export const number = 999; 17 | 18 | export interface ICat{ 19 | name: string; 20 | age: number; 21 | } 22 | 23 | export default { 24 | name: '코드팩토리', 25 | age: 23, 26 | } -------------------------------------------------------------------------------- /9_class/4_class_as_type_and_value.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Class as Type and Value 3 | */ 4 | class Dog { 5 | name: string; 6 | 7 | constructor(name: string){ 8 | this.name = name; 9 | } 10 | 11 | bark(){ 12 | return `${this.name}가 짖습니다`; 13 | } 14 | } 15 | 16 | let ori = new Dog('오리'); 17 | console.log(ori.bark()); 18 | 19 | // ori = '오리'; 20 | 21 | ori = { 22 | name: '별이', 23 | bark(){ 24 | return `${this.name}가 짖습니다.`; 25 | } 26 | } 27 | 28 | console.log(ori); -------------------------------------------------------------------------------- /1_basic/6_casting.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Casting 3 | * 4 | * TS에서 Casting을 하면 JS에서는 적용이 안된다. 5 | */ 6 | let codefactory = 'code factory'; 7 | let testNumber = 3; 8 | 9 | console.log(codefactory.toUpperCase()); 10 | // console.log(testNumber.toUpperCase()); 11 | 12 | let sampleNumber: any = 5; 13 | // console.log(sampleNumber.toUpperCase()); 14 | let stringVar = sampleNumber as string; 15 | 16 | console.log(typeof (sampleNumber as string)); 17 | 18 | let number = 5; 19 | 20 | console.log((number as any).toUpperCase()); -------------------------------------------------------------------------------- /10_generic/2_generic_in_interface.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Generic in Interface 3 | */ 4 | interface Cache { 5 | data: T[]; 6 | lastUpdate: Date; 7 | } 8 | 9 | const cache1: Cache = { 10 | data: ['data1', 'data2'], 11 | lastUpdate: new Date(), 12 | } 13 | 14 | // const cach2: Cache = { 15 | // data: [123, 456], 16 | // lastUpdate: new Date(), 17 | // } 18 | 19 | interface DefaultGeneric{ 20 | data:T[]; 21 | } 22 | 23 | // const cache3: DefaultGeneric = { 24 | // data: [123, 456], 25 | // } -------------------------------------------------------------------------------- /12_experimental_decorator/5_parameter_decorator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Parameter Decorator 3 | */ 4 | class Cat { 5 | name: string; 6 | 7 | constructor(name: string){ 8 | this.name = name; 9 | } 10 | 11 | dance(@LogParam adj: string){ 12 | console.log(`${this.name}가 ${adj} 춤을 춥니다.`); 13 | } 14 | } 15 | 16 | const cat = new Cat('냥이'); 17 | cat.dance('신나게'); 18 | 19 | function LogParam(target: any, propertyKey: string, paramIndex: number){ 20 | console.log(`${paramIndex}번째 파라미터인 ${propertyKey}가 입력됐습니다.`); 21 | } -------------------------------------------------------------------------------- /11_utility_type/1_partial_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Partial Type 3 | */ 4 | interface Idol{ 5 | name: string; 6 | age: number; 7 | groupName: string; 8 | } 9 | 10 | const yuJin: Idol = { 11 | name: '안유진', 12 | age: 23, 13 | groupName: '아이브', 14 | } 15 | 16 | function updateIdol(original: Idol, updates: Partial): Idol{ 17 | return { 18 | ...original, 19 | ...updates, 20 | } 21 | } 22 | 23 | console.log(updateIdol(yuJin, { 24 | age: 27, 25 | name: '코드팩토리', 26 | groupName: '주식회사 코드팩토리', 27 | })); -------------------------------------------------------------------------------- /2_union_and_intersection/2_intersection_basics.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Intersection 3 | * 4 | * And 5 | */ 6 | interface Human{ 7 | name: string; 8 | age: number; 9 | } 10 | 11 | interface Contacts{ 12 | phone: string; 13 | address: string; 14 | } 15 | 16 | type HumanAndContacts = Human & Contacts; 17 | 18 | let humanAndContacts: HumanAndContacts = { 19 | name: '코드팩토리', 20 | age: 32, 21 | phone: '01012341234', 22 | address: '서울시' 23 | }; 24 | 25 | type NumberAndString = number & string; 26 | 27 | // let numberAndString: NumberAndString = never; -------------------------------------------------------------------------------- /8_object/4_optional_and_undefined_property.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Optional and Undefined Property 3 | */ 4 | interface Dog { 5 | name: string; 6 | age: number; 7 | // 종을 모르면 undefined 8 | breed?: string; 9 | } 10 | 11 | const byulE: Dog = { 12 | name: '별이', 13 | age: 12, 14 | breed: '미니핀', 15 | } 16 | 17 | const ori: Dog = { 18 | name: '오리', 19 | age: 3, 20 | } 21 | 22 | interface Cat{ 23 | name: string; 24 | age: number; 25 | breed?: string | undefined; 26 | } 27 | 28 | const nabi: Cat = { 29 | name: '나비', 30 | age: 7, 31 | // breed: undefined, 32 | } -------------------------------------------------------------------------------- /9_class/8_abstract_class.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Abstract class 3 | */ 4 | abstract class ModelWithId { 5 | id: number; 6 | 7 | constructor(id: number) { 8 | this.id = id; 9 | } 10 | } 11 | 12 | // const modelWithId = new ModelWithId(123); 13 | 14 | class Product extends ModelWithId{ 15 | 16 | } 17 | 18 | const product = new Product(1); 19 | product.id; 20 | 21 | abstract class ModelWithAbstractMethod{ 22 | abstract shout(name: string): string; 23 | } 24 | 25 | class Person extends ModelWithAbstractMethod{ 26 | shout(name: string): string { 27 | return '소리질러~'; 28 | } 29 | } -------------------------------------------------------------------------------- /15_import_and_export/3_multiple_ways_to_import_and_export.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Multiple Ways to Import and Export 3 | */ 4 | // import { IdolModel as IM, rose, number, ICat } from "./2_export_1"; 5 | 6 | // console.log(new IM('아이유', 32)); 7 | // console.log(new IdolModel('아이유', 32)); 8 | 9 | // import * as allTogether from './2_export_1'; 10 | 11 | // console.log(allTogether.number); 12 | // console.log(allTogether.rose); 13 | 14 | // import cf, {rose, number} from './2_export_1'; 15 | 16 | // console.log(cf); 17 | // console.log(rose); 18 | 19 | // baseUrl 20 | import { IdolModel } from "15_import_and_export/2_export_1"; -------------------------------------------------------------------------------- /9_class/1_defining_class.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Class 선언하기 3 | */ 4 | class SampleClass { } 5 | 6 | class Game { 7 | name: string; 8 | country: string; 9 | download: number; 10 | 11 | constructor(name: string, country: string, download: number){ 12 | this.name = name; 13 | this.country = country; 14 | this.download = download; 15 | } 16 | 17 | introduce(){ 18 | return `${this.name}은 ${this.country}에서 제작된 ${this.download}개의 다운로드를 달성한 게임입니다.`; 19 | } 20 | } 21 | 22 | const starcraft = new Game( 23 | 'Star Craft', 24 | 'USA', 25 | 10000000, 26 | ); 27 | 28 | const retVal = starcraft.introduce(); 29 | 30 | // starcraft.changeGame(); -------------------------------------------------------------------------------- /3_function/2_function_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Function Type 3 | */ 4 | type Mapper = (x: string) => string; 5 | 6 | const runner = (callback: Mapper)=>{ 7 | return ['안유진', '장원영', '레이'].map( 8 | callback, 9 | ); 10 | } 11 | 12 | console.log(runner((x) => `아이브 멤버: ${x}`)); 13 | 14 | type MultiplyTwoNumbers = (x: number, y: number) => number; 15 | 16 | const multiplyTwoNumbers: MultiplyTwoNumbers = (x, y)=>{ 17 | return x+y; 18 | } 19 | 20 | /** 21 | * Interface로 함수 타입 선언하기 22 | */ 23 | interface IMultiplyTwoNumbers{ 24 | (x: number, y: number): number; 25 | } 26 | 27 | const multiplyTwoNumbers3: IMultiplyTwoNumbers = (x, y) => { 28 | // return true; 29 | return x * y; 30 | } -------------------------------------------------------------------------------- /9_class/3_property_initialization.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Property Initialization 3 | */ 4 | class Person { 5 | // 일반적인 필수값 선언법 6 | name: string; 7 | // 초기값 제공 선언법 8 | age: number = 23; 9 | // optional 값 선언법 10 | pet?: string; 11 | // type of undefined 선언법 12 | petAge: number | undefined; 13 | 14 | constructor(name: string, pet?: string){ 15 | this.name = name; 16 | this.pet = pet; 17 | } 18 | } 19 | 20 | class RouteStack{ 21 | stack!: string[]; 22 | 23 | constructor(){ 24 | this.initialize(); 25 | } 26 | 27 | initialize(){ 28 | this.stack = []; 29 | } 30 | } 31 | 32 | const routeStack = new RouteStack(); 33 | console.log(routeStack); -------------------------------------------------------------------------------- /5_any_unknown_never/1_loop_holes_of_any.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Loopholes of Any 3 | */ 4 | let number: number; 5 | number = 10; 6 | 7 | // number.toUpperCase(); 8 | 9 | // (number as any).toUpperCase(); 10 | 11 | const multiplyTwo = (x: number, y: number) => { 12 | return x * y; 13 | } 14 | 15 | let args1: any = '코드팩토리'; 16 | let args2: any = true; 17 | 18 | multiplyTwo(args1, args2); 19 | // multiplyTwo('코드팩토리', true); 20 | 21 | let iu:any = {name: '아이유', age: 30}; 22 | iu; 23 | 24 | const callbackRunner = (x: number, y: number, callback: any)=>{ 25 | return callback(x); 26 | } 27 | 28 | const callback = (x:number, y: number)=>{ 29 | return x * y; 30 | } 31 | 32 | console.log(callbackRunner(5, 4, callback)); -------------------------------------------------------------------------------- /10_generic/3_generic_in_type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Generic in Type 3 | */ 4 | type GenericSimpleType = T; 5 | 6 | const genericString: GenericSimpleType = '코드팩토리'; 7 | // const genericString2: GenericSimpleType = '코드팩토리'; 8 | 9 | interface DoneState{ 10 | data: T[]; 11 | } 12 | 13 | interface LoadingState{ 14 | requestedAt: Date; 15 | } 16 | 17 | interface ErrorState { 18 | error: string; 19 | } 20 | 21 | type State = DoneState | LoadingState | ErrorState; 22 | 23 | let state: State = { 24 | data: ['123', '456'], 25 | } 26 | 27 | state = { 28 | requestedAt: new Date() 29 | } 30 | 31 | state = {error: 'error'}; 32 | 33 | let state2: State = { 34 | data: [123, 456] 35 | } -------------------------------------------------------------------------------- /6_array/3_multi_dimension_array.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Multi Dimension Array 3 | */ 4 | /** 5 | * (1) 6 | * [1,2,3] 7 | * 8 | * (2) 9 | * [ 10 | * [1,2,3], 11 | * [1,2,3] 12 | * ] 13 | * 14 | * (3) 15 | * [ 16 | * [ 17 | * [1,2,3] 18 | * ] 19 | * ] 20 | */ 21 | 22 | const numb2DArr: number[][] = [ 23 | [1, 2, 3], 24 | [4, 5, 6] 25 | ] 26 | 27 | const str2DArr = [ 28 | ['1', '2', '3'], 29 | ['4', '5', '6'], 30 | ] 31 | 32 | const strAndNumbArr: (number | string)[][] = [ 33 | [1, '2', 3], 34 | ['4', 5, '6'], 35 | ] 36 | 37 | let strArrOrNumbArr: string[][] | number[][] = [ 38 | [1, 2, 3], 39 | [4, 5, 6], 40 | ] 41 | 42 | strArrOrNumbArr = [ 43 | ['1', '2', '3'], 44 | ] 45 | 46 | for(let arr of numb2DArr){ 47 | for(let item of arr){ 48 | 49 | } 50 | } -------------------------------------------------------------------------------- /10_generic/8_generic_in_promise.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Generic in Promise 3 | */ 4 | const afterTwoSeconds = function () { 5 | return new Promise((resolve) => { 6 | setTimeout(() => { 7 | resolve('done'); 8 | }, 2000) 9 | }) 10 | } 11 | 12 | const runner = async function () { 13 | const res = await afterTwoSeconds(); 14 | console.log(res); 15 | } 16 | 17 | runner(); 18 | 19 | const afterOneSecond = function(): Promise{ 20 | return new Promise((resolve) => { 21 | setTimeout(() => { 22 | resolve('done'); 23 | }, 1000) 24 | }) 25 | } 26 | 27 | const runner2 = async function () { 28 | const res = await afterOneSecond(); 29 | console.log(res); 30 | } 31 | 32 | runner2(); 33 | 34 | const runner3 = async function(){ 35 | return 'string return'; 36 | } -------------------------------------------------------------------------------- /12_experimental_decorator/3_accessor_decrator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Accessor Decorator 3 | */ 4 | class Rectangle{ 5 | #height: number; 6 | #width: number; 7 | 8 | constructor(height: number, width: number){ 9 | this.#height = height; 10 | this.#width = width; 11 | } 12 | 13 | @Configurable(false) 14 | get height(){ 15 | return this.#height; 16 | } 17 | 18 | @Configurable(true) 19 | get width(){ 20 | return this.#width; 21 | } 22 | } 23 | 24 | function Configurable(configurable: boolean){ 25 | return function(target: any, propertyKey: string, descriptor: PropertyDescriptor){ 26 | descriptor.configurable = configurable; 27 | } 28 | } 29 | 30 | const rectangle = new Rectangle(100, 200); 31 | 32 | console.log(Object.getOwnPropertyDescriptors(Rectangle.prototype)); -------------------------------------------------------------------------------- /10_generic/7_generic_in_implementation.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Generic in Implementation 3 | */ 4 | 5 | interface Singer { 6 | name: T; 7 | sing(year: V): void; 8 | } 9 | 10 | class Idol implements Singer { 11 | name: string; 12 | 13 | constructor(name: string) { 14 | this.name = name; 15 | } 16 | 17 | sing(year: number): void { 18 | console.log(`[${year}] ${this.name}이 노래를 부릅니다.`) 19 | } 20 | } 21 | 22 | const yuJin = new Idol('안유진'); 23 | yuJin.sing(2003); 24 | 25 | class Idol2 implements Singer { 26 | name: T; 27 | 28 | constructor(name: T) { 29 | this.name = name; 30 | } 31 | 32 | sing(year: V): void { 33 | console.log(`[${year}] ${this.name}이 노래를 부릅니다.`) 34 | } 35 | } 36 | 37 | const wonYoung = new Idol2('장원영'); 38 | wonYoung.sing(2003); -------------------------------------------------------------------------------- /3_function/3_overloading.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Overloading 3 | */ 4 | /** 5 | * 파라미터를 6 | * 1) 하나를 받거나 7 | * 2) 세개를 받는 함수 8 | */ 9 | 10 | function stringOrStrings(members: string): string; 11 | function stringOrStrings(member1: string, member2: string, member3:string): string; 12 | // function stringOrStrings(): string; 13 | 14 | /** 15 | * 만약에 하나의 파라미터만 입력받는다면 16 | * 아이돌 멤버들을 하나의 스트링으로 입력받는다. 17 | * 예) '안유진, 장원영, 레이' 18 | * 19 | * 만약에 세개의 파라미터를 받는다면 20 | * 각각 아이돌을 각각의 파라미터의 값으로 입력한다. 21 | * 예) '안유진', '장원영', '레이' 22 | */ 23 | function stringOrStrings(memberOrMembers: string, member2?: string, member3?:string) :string{ 24 | if(member2 && member3){ 25 | return `아이브: ${memberOrMembers}, ${member2}, ${member3}`; 26 | }else{ 27 | return `아이브: ${memberOrMembers}`; 28 | } 29 | } 30 | 31 | console.log(stringOrStrings('안유진, 장원영, 레이')); 32 | console.log(stringOrStrings('안유진', '장원영', '레이')); 33 | // console.log(stringOrStrings('안유진', '장원영')); -------------------------------------------------------------------------------- /8_object/6_object_intersection.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Object Intersection 3 | */ 4 | type PrimitiveIntersection = string & number; 5 | 6 | type PersonType = { 7 | name: string; 8 | age: number; 9 | } 10 | 11 | type CompanyType = { 12 | company: string; 13 | companyRegistrationNumber: string; 14 | } 15 | 16 | type PersonAndCompany = PersonType & CompanyType; 17 | 18 | const jisoo: PersonAndCompany = { 19 | name: '지수', 20 | age: 32, 21 | company: 'YG', 22 | companyRegistrationNumber: 'xxxyyyyzzzz', 23 | } 24 | 25 | type PetType = { 26 | petName: string; 27 | petAge: number; 28 | } 29 | 30 | type CompanyOrPet = PersonType & (CompanyType | PetType); 31 | 32 | const companyOrPet: CompanyOrPet = { 33 | // PersonType 34 | name: '코드팩토리', 35 | age: 32, 36 | 37 | // CompanyType 38 | company: '주식회사 코드팩토리', 39 | companyRegistrationNumber: 'xxxyyyzzz', 40 | 41 | // PetType 42 | petName: '오리', 43 | petAge: 8, 44 | } -------------------------------------------------------------------------------- /10_generic/4_generic_in_class.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Class에서 Generic 사용하기 3 | */ 4 | class Pagination{ 5 | data: Data[] = []; 6 | message?: Message; 7 | lastFetchedAt?: Date; 8 | } 9 | 10 | const pgData = new Pagination(); 11 | pgData.data; 12 | pgData.message; 13 | pgData.lastFetchedAt; 14 | 15 | class Pagination2{ 16 | data: Data[] = []; 17 | message?: Message; 18 | lastFetchedAt?: Date; 19 | 20 | constructor(data: Data[], message?: Message, lastFetchedAt?: Date){ 21 | this.data = data; 22 | this.message = message; 23 | this.lastFetchedAt = lastFetchedAt; 24 | } 25 | } 26 | 27 | const pagination2 = new Pagination2([123, 456]); 28 | 29 | pagination2.data; 30 | pagination2.message; 31 | pagination2.lastFetchedAt; 32 | 33 | class DefaultGeneric{ 34 | data: T[] = []; 35 | } 36 | 37 | const defaultGeneric = new DefaultGeneric(); 38 | defaultGeneric.data; -------------------------------------------------------------------------------- /9_class/9_visibility_keyword.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Visibility Keyword 3 | * 4 | * 1) public (기본값) - 어디서든 접근이 가능하다 5 | * 2) protected - 현재 클래스 및 하위 (자식) 클래스에서 접근 가능하다. 6 | * 3) private - 현재 클래스 내부에서만 접근 가능하다. 7 | */ 8 | class PropertyTestParent{ 9 | public publicProperty = 'public property'; 10 | protected protectedProperty = 'protected property'; 11 | private privateProperty = 'private property'; 12 | #jsPrivateProperty = 'js private property'; 13 | 14 | test(){ 15 | this.publicProperty; 16 | this.protectedProperty; 17 | this.privateProperty; 18 | this.#jsPrivateProperty 19 | } 20 | } 21 | 22 | class PropertyTestChild extends PropertyTestParent{ 23 | test(){ 24 | this.publicProperty; 25 | this.protectedProperty; 26 | // this.privateProperty; 27 | // this.#jsPrivateProperty 28 | } 29 | } 30 | 31 | const instance = new PropertyTestChild(); 32 | 33 | instance.publicProperty; 34 | // instance. -------------------------------------------------------------------------------- /16_extras/1_infer_keyword.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Infer Keyword 3 | * 4 | * 추론한다 5 | * 6 | * (Inferring Type in Conditional Type) 7 | * 8 | * Infer Keyword는 Conditional Type에서만 사용 가능한 키워드다. 9 | * 그러니 extends 키워드를 사용했을때 extend 한 대상에서 타입을 한번 더 추론하는 역할을한다. 10 | */ 11 | 12 | // 1) 가장 많이 사용하는 예제 13 | // Flattening -> Array를 벗겨낼때 14 | // string[] -> string 15 | // string[][] -> string[] 16 | type Flatten = Type extends Array ? ElementType[][] : Type; 17 | type Flatten2 = Type extends (infer ElementType)[] ? ElementType[][][] : Type; 18 | 19 | type StringArray = Flatten2; 20 | type NumberArray = Flatten2; 21 | type TwoDArray = Flatten2; 22 | 23 | // 2) Return Type 추론 24 | type InferReturnType = Type extends (...args:any[]) => infer ReturnType ? ReturnType : Type; 25 | 26 | type NumberArray2 = InferReturnType; 27 | 28 | type StringFunc = InferReturnType<()=> string>; 29 | type NumberFunc = InferReturnType<()=> number>; -------------------------------------------------------------------------------- /3_function/5_type_predicate.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Type Predicate 3 | */ 4 | function isNumber(input: any): input is number{ 5 | return typeof input === 'number'; 6 | } 7 | 8 | console.log(isNumber(10)); 9 | 10 | function isNumberRetBool(input: any): boolean{ 11 | return typeof input === 'number'; 12 | } 13 | 14 | let number: any = 5; 15 | 16 | if(isNumberRetBool(number)){ 17 | number; 18 | } 19 | 20 | if(isNumber(number)){ 21 | number; 22 | } 23 | 24 | interface Doge{ 25 | name: string; 26 | age: number; 27 | } 28 | 29 | interface Cat{ 30 | name: string; 31 | breed: string; 32 | } 33 | 34 | type DogeOrCat = Doge | Cat; 35 | 36 | function isDoge(animal: DogeOrCat): animal is Doge{ 37 | return (animal as Doge).age !== undefined; 38 | } 39 | 40 | const doge: DogeOrCat = Math.random() > 0.5 ? { 41 | name: '도지', 42 | age: 32, 43 | } : { 44 | name: '오리', 45 | breed: '코리안 길냥이' 46 | } 47 | 48 | if(isDoge(doge)){ 49 | doge; 50 | }else{ 51 | doge; 52 | } -------------------------------------------------------------------------------- /6_array/1_problems_with_array_in_js.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Problems with Array in JS 3 | */ 4 | const number = [1, '2', 3, '4', 5]; 5 | 6 | let strings: string[] = ['1', '2', '3']; 7 | 8 | // strings.push(1); 9 | 10 | let stringsOrNumbersArray: (string | number)[] = [ 11 | 1, 12 | '2', 13 | 3, 14 | '4', 15 | ] 16 | 17 | let stringArrNumberArr: string[] | number[] = [ 18 | 1, 19 | 2, 20 | 3, 21 | ] 22 | 23 | stringArrNumberArr = [ 24 | '1', '2', '3', 25 | ] 26 | 27 | let stringOrNumberArr: string | number[] = [ 28 | 1, 2, 3 29 | ] 30 | 31 | stringOrNumberArr = '3'; 32 | 33 | let boolsArr = [true, false, true]; 34 | 35 | boolsArr.push(false); 36 | 37 | // boolsArr.push(1); 38 | 39 | const onlyString = ['1', '2', '3']; 40 | const onlyNumbers = [1, 2, 3]; 41 | 42 | for(let i = 0; i < onlyString.length; i++){ 43 | let item = onlyString[i]; 44 | } 45 | 46 | for(let item of onlyNumbers){ 47 | 48 | } 49 | 50 | let number3 = onlyNumbers[0]; 51 | 52 | let number4 = onlyNumbers[9999]; -------------------------------------------------------------------------------- /8_object/3_nested_object.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Nested Object 3 | */ 4 | 5 | type NestedPerson = { 6 | identity:{ 7 | name: string; 8 | age: number; 9 | }, 10 | nationality: string; 11 | } 12 | 13 | const codefactory: NestedPerson = { 14 | identity:{ 15 | name: '코드팩토리', 16 | age: 32, 17 | }, 18 | nationality: '한국인', 19 | } 20 | 21 | type TPerson = { 22 | identity: TPersonIdentity, 23 | nationality: string; 24 | } 25 | 26 | type TPersonIdentity = { 27 | name: string; 28 | age: number; 29 | } 30 | 31 | const iu: TPerson = { 32 | identity:{ 33 | name: '아이유', 34 | age: 32, 35 | }, 36 | nationality: '한국인', 37 | } 38 | 39 | interface IPerson { 40 | identity: IPersonIdentity; 41 | nationality: string; 42 | } 43 | 44 | interface IPersonIdentity{ 45 | name: string; 46 | age: number; 47 | } 48 | 49 | const yuJin: IPerson = { 50 | identity:{ 51 | name: '안유진', 52 | age: 22, 53 | }, 54 | nationality: '한국인', 55 | } -------------------------------------------------------------------------------- /10_generic/6_generic_in_method.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Method에서 Generic 사용하기 3 | */ 4 | 5 | class Idol{ 6 | id: T; 7 | name: string; 8 | 9 | constructor(id: T, name: string) { 10 | this.id = id; 11 | this.name = name; 12 | } 13 | 14 | sayHello