Set Up
touch index.ts && tsc --init
이라는 명령어를 쳐서 프로젝트를 만들어 줍니다. 그러면 tsconfig.json이라는 파일이 생성될 것이고, 아래와 같이 작성해 줍니다.
tsconfig.json
{ "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ /* Projects */ // "incremental": true, /* Enable incremental compilation */ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ "target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ /* Modules */ "module": "commonjs", /* Specify what module code is generated. */ // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "resolveJsonModule": true, /* Enable importing .json files */ // "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ /* Emit */ "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ // "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ "outDir": "./dist", /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ // "newLine": "crlf", /* Set the newline character for emitting files. */ // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ /* Type Checking */ "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */ } }
그리고 tsc라고 명령어를 쳐주면 index.ts파일을 인식해서 아래와 같이 index.d.ts, sourcemap, js파일 3개를 만들어 주게 됩니다.

Implicit Types vs Explicit Types
let c = []; c.push("1");
다음과 같은 코드를 보면 당연히 JS에서는 돌아가는 코드일 것입니다. 하지만 다음을 보시죠
let c = [1, 2, 3]; c.push("1");
이는 c배열이 의도한 대로 사용되지 않고 있는 모습을 보고 있는 겁니다. JS에서는 이를 무시하고 runtime Error를 낼 것입니다. 하지만 Typescript에서는 "string을 number type에 대입할 수 없다며 컴파일 오류를 띄우게 되죠" 이는 암묵적으로 typescript에서 c에게 number[]라는 타입을 지정해 주었기 때문입니다. 저희는 이와는 다르게 아래와 같이 명시적으로 타입을 지정해 줄 수도 있습니다.
let Arr: number[] = [1, 2, 3]; Arr.push(1);
다음과 같이 명시적 표현을 통해 typescript가 타입을 추론할 수 있게 할 수 있습니다. 하지만 보통 명시적 표현은 최소한으로 사용하는게 좋습니다. typescript가 추론하게 하는게 더 낫기 때문이죠. 다음의 예시를 보시죠
let Arr: number[] = [1, 2, 3]; Arr.push(1); const player = { name: "hyunseo", };
다음과 같이 작성해 주면 typescript는 player를 아래와 같이 추론하게 됩니다. 이를 암묵적 추론이라고 합니다.

Types of TS - 1
배열은 아래와 같이 타입을 지정해 주게 됩니다.
let a_ = [1, 2]; let b_: string[] = ["il", "1"]; let c_: boolean[] = [true];
객체는 아래와 같이 타입을 지정하게 됩니다. 이떄 Optional Chaining이라는 기술을 사용해 볼 수 있습니다. 그러면 객체에 그 key가 았을 수도, 아니면 없을 수도 있다는 얘기 입니다.
type Player = { name: string; age?: number; }; const player1: Player = { name: "hyunseo", }; const palyer2: Player = { name: "hyunseo2", age: 21, };
또한 Player.age의 타입이 ?: 을 해주게 되어 number | undefined가 되었습니다. 따라서 아래와 같이 작성해 주면 오류가 발생하게 됩니다.
type Player = { name: string; age?: number; }; const player1: Player = { name: "hyunseo", }; const palyer2: Player = { name: "hyunseo2", age: 21, }; // error if (player1.age < 10) { console.log(player1.age); }
그 이유는 player1에 age라는 속성이 없을 수도 있기 때문이죠, 따라서 아래와 같이 작성해 주어야 합니다.
type Player = { name: string; age?: number; }; const player1: Player = { name: "hyunseo", }; const palyer2: Player = { name: "hyunseo2", age: 21, }; if (player1.age && player1.age < 10) { console.log(player1.age); }
또한 이러한 객체를 반환하는 함수는 typescript로 아래와 같이 작성해 줄 수 있습니다.
type Player = { name: string; age?: number; }; const player1: Player = { name: "hyunseo", }; const palyer2: Player = { name: "hyunseo2", age: 21, }; if (player1.age && player1.age < 10) { console.log(player1.age); } const playerMaker = (name: string): Player => ({ name, }); const hyunseo = playerMaker("hyunseo3"); hyunseo.age = 22;
이렇게 함수를 반환하는 타입은 명시적으로 함수를 사용할 떄 실수하지 않게 작성해 주는 것이 좋습니다.
Types of TS - 2
다음으로는 readonly가 있습니다. 이는 속성을 바꿀 수 없게 할 수 있습니다. 다음과 같이 말이죠
type Player = { readonly name: string; age?: number; }; const playerMaker = (name: string): Player => ({ name, }); const hyunseo = playerMaker("hyunseo3"); hyunseo.age = 22; // error hyunseo.name = "hyunseo_clone";
같은 원래로 아래 코드도 오류를 내게 됩니다.
const numbers: readonly number[] = [1, 2, 3, 4]; // error numbers.push(1);
다음은 Tuple 타입입니다. 아래와 같이 원하는 순서에 맞는 타입을 가져야 할 때 사용합니다.
const player: [string, number, boolean] = ["nico", 1, true];
다음은 any타입입니다. any는 타입스크랩트로부터 빠져나오고 싶을 떄 쓰는 타입입니다. 하지만 추천하지는 않는데 아래와 같이 작성될 수 있는 위험이 있기 때문입니다.
let a: any[] = [1, 2, 3, 4]; const b: any = true; a + b;
이러면 typescript를 쓰는 이유가 없어지므로 매우 이상해 집니다. 하지만 어떠한 특수한 경우 꼭 any가 필요한 경우가 있으므로, 알아둬야 합니다.
Types of TS - 2
never타입은 아직 타입이 정해지지 않았을 때 쓰는 타입입니다 이의 사용예제는 다음과 같습니다.
let a: unknown; if (typeof a === "number") { let b = a + 1; } if (typeof a === "string") { let b = a.toUpperCase(); }
꼭 사용할 때는 타입을 확인하고 사용해 주어야 하죠. 이는 변수의 타입을 미리 알지 못할 때 사용합니다.
다음은 void타입입니다. 이는 함수의 반환값이 없을 때 사용합니다. 이의 예제를 보면 이해가 빨리 되실 겁니다. C, C++에서 많이 봤듯이 작성해 주면 됩니다.
function hello(): void { console.log("x"); } const a = hello(); // error a.toUpperCase();
다음과 같이 void에 toUpperCase()를 하면 오류가 뜹니다.
다음은 never타입입니다. 이는 아무것도 반환하지 않아야 할 때 사용합니다. Erorr를 반환하거나 전혀 나와야 하지 않을 곳에서의 변수 명을 지정해 줄 때 말이죠, 아래의 예시를 보시죠
function hello(name: string | number) { if (typeof name === "string") { } else if (typeof name === "number") { } else { // never } } function Error_return(): never { throw new Error("hello"); }
'Web > TypeScript' 카테고리의 다른 글
Typescript Practice - Block Chain Project -implements (0) | 2022.05.08 |
---|---|
Typescript Practice - Block Chain Project - Basic (0) | 2022.05.07 |
TypeScript Practice - Class, Interface (0) | 2022.05.07 |
Typescript Practice - Functions (0) | 2022.05.07 |