정보실

웹학교

정보실

javascript 초보자를위한 TypeScript Tutorial : The Missing Guide

본문

TypeScript 란 무엇이며 왜 사용해야 합니까? 

초보자를 위한 이 TypeScript 자습서를 통해 자세히 알아보고 몇 분 안에 JavaScript 코드에 유형을 추가하십시오!


https://www.valentinog.com/blog/typescript/ 


초보자를 위한 TypeScript 튜토리얼 :이 안내서의 대상 


다음 가이드는 TypeScript에 대해 더 배우고 자 하는 JavaScript 개발자를 위한 TypeScript 자습서입니다. 

그것은 우리가 갈 때 기초에 대한 포인터를 제공 할지라도 "바닐라"JavaScript에 대한 적절한 지식이 인정된다는 것을 의미합니다.


이 자습서를 시작하기 전이나 후에 JavaScript 기술을 새로 고치려면 Github에서 무료로 제공되는 "Little JavaScript Book"과 PDF / ePub / Mobi를 확인하십시오.


TypeScript와 "초보자"라는 단어가 동일한 자습서에 속합니까? 이 안내서를 작성하기 전에 확실하지 않았지만 매일 TypeScript에 관심이 있는 초보자가 많이 있습니다. 그렇게 하기로 결정했다면, JavaScript와 함께 초기에 TypeScript를 배우는 것은 어려울 것입니다. 하지만 장기적으로는 돈을 지불해야 합니다. 계속가요! 그런 경우라면 계속 읽으십시오.


시작하기 전에 시스템에 최신 버전의 Node.js가 설치되어 있는지 확인하십시오.


그리고 이제 독서를 즐기십시오!


초보자를 위한 TypeScript 자습서 : TypeScript 란 무엇입니까? 


공식 웹 사이트의 정의에 따르면“타입 화 된 자바 스크립트 슈퍼 세트”라고 되어 있지만“슈퍼 셋”이 무엇인지 그리고“타입이 무엇”이 무엇인지 알고 있다고 가정합니다. 작업을 단순하게 유지하기 위해 TypeScript를 JavaScript의 "상위 계층"이라고 생각할 수 있습니다.


TypeScript는 편집기에서 TypeScript 코드를 작성할 수 있으므로 레이어입니다. 컴파일 후 모든 TypeScript 내용이 사라지고 평범하고 간단한 JavaScript가 남습니다.


컴파일 단계의 아이디어가 혼란스러우면 JavaScript가 이미 컴파일 된 후 해석된다는 것을 명심하십시오. 코드를 읽고 실행하는 JavaScript 엔진이 있습니다.


그러나 JavaScript 엔진은 TypeScript 코드를 읽을 수 없으므로 모든 TypeScript 파일은 컴파일이라는 "번역 전"프로세스를 거쳐야 합니다. 첫 번째 컴파일 단계 후에는 순수한 JavaScript 코드가 남아 브라우저에서 실행할 수 있습니다. 나중에 TypeScript 컴파일이 수행되는 방법을 볼 수 있습니다.


지금은 TypeScript가 특별한 종류의 JavaScript이지만 브라우저에서 실행하기 전에 "번역기"가 필요하다는 점을 명심하십시오.


초보자를 위한 TypeScript 튜토리얼 : 왜 TypeScript? 


처음에는 TypeScript가 왜 의미가 있는지 정확하게 이해하지 못합니다. "TypeScript의 요점은 무엇입니까?" 친구에게 좋은 질문입니다.


실제로 코드에서 심각하고 어리석은 실수를 잡는 즉시 이점을 보게 될 것입니다. 더 중요한 것은 코드베이스가 체계적이고 거의 자체 문서화 되는 것입니다. 에디터에서 자동 완성 기능이 향상 되어도 좋은 결과를 얻을 수 있지만 좋은 부작용입니다.


어쨌든, TypeScript가 쓸모 없거나 (TypeScript 세금) 너무 어색하다는 트위터나 “주황색 웹 사이트”에 새 스레드가 나타납니다. 예를 들면 다음과 같습니다.


IT의 거의 모든 것과 마찬가지로 바리케이드의 양쪽에 당파자가 있습니다. TypeScript의 견해와 지지자가 있지만 중요한 것은 TypeScript가 견고한 도구이며 도구 벨트에 넣는 것이 해가 되지 않는다는 것입니다.


여기서 목표는 도구를 보여주고 TypeScript에 대한 자신의 아이디어를 형성하는 데 도움이 되는 것입니다.


초보자를 위한 TypeScript 자습서 : TypeScript 설정 


설정? 왜 그래? TypeScript는 단순한 언어가 아닙니까? 거의. TypeScript에는 TypeScript 코드를 JavaScript 코드로 컴파일하는 바이너리도 있습니다. 브라우저는 TypeScript를 이해하지 못합니다. 바이너리를 설치하자. 새 폴더 안에 새 노드 프로젝트를 작성하십시오.


  1. mkdir typescript-tutorial && cd $_
  2. npm init -y

다음을 사용하여 TypeScript를 설치하십시오.


npm i typescript --save-dev 


다음으로 TypeScript 컴파일러를 쉽게 실행할 수 있도록 노드 스크립트를 구성하십시오.


  1. "scripts": {
  2. "tsc": "tsc"
  3. },

tsc는 TypeScript 컴파일러를 나타내며 컴파일러가 실행될 때마다 프로젝트 폴더에서 tsconfig.json이라는 파일을 찾습니다. 다음을 사용하여 TypeScript 용 구성 파일을 생성 해 보겠습니다.


npm run tsc -- --init 


모든 것이 잘되면“TS6071 : tsconfig.json 파일을 성공적으로 만들었습니다”라는 메시지가 나타나고 프로젝트 폴더에 새 파일이 표시됩니다. 이제 침착하게 tsconfig.json은 무서운 구성 파일입니다. 모든 요점을 알 필요는 없습니다. 다음 섹션에서는 시작 관련 비트만 볼 수 있습니다.


TypeScript 컴파일러 구성 


파일을 터치하기 전에 git repo를 초기화하고 원본 tsconfig.json을 커밋하는 것이 좋습니다. 구성 옵션 중 일부만 남겨두고 나머지는 모두 제거합니다. 나중에 버전을 원본과 비교할 수 있습니다.


시작하려면 tsconfig.json을 열고 모든 원본 컨텐츠를 다음으로 바꾸십시오.


  1. {
  2. "compilerOptions": {
  3. "target": "es5",
  4. "strict": true
  5. }
  6. }

파일을 저장하고 닫습니다. 우선 tsconfig.json이 무엇인지 궁금 할 것입니다. 이 구성 파일은 TypeScript 컴파일러와 TypeScript를 지원하는 모든 코드 편집기에서 읽습니다.


TypeScript는 "vanilla"JavaScript로 컴파일 됩니다. 주요 대상은 원하는 JavaScript 버전 인 ES5 (또는 최신 릴리스)를 결정합니다.


tsconfig.json의 “엄격성” 수준에 따라 적절한 유형 주석을 코드에 추가하지 않으면 컴파일러와 편집기가 이를 준수합니다 (1 분 후 더 자세히 설명).


엄격하게 true로 설정하면 TypeScript는 코드에서 유형 검사의 최대 수준을 다른 것들 중에서 가능하게 합니다.

  • noImplicitAny true : 변수에 정의 된 유형이 없는 경우 TypeScript가 불평합니다
  • alwaysStrict true : 엄격 모드는 우발적 인 전역 변수, 기본 "this"바인딩 등을 방지하는 JavaScript의 안전한 메커니즘입니다. "alwaysStrict"가 true로 설정되면 TypeScript는 모든 JavaScript 파일의 맨 위에 "엄격한 사용"을 내 보냅니다.

더 많은 구성 옵션을 사용할 수 있습니다. 시간이 지남에 따라 더 많은 정보를 얻을 수 있게 되었으므로 지금 위의 두 가지 옵션은 시작하는 데 필요한 모든 것입니다. 그런데 "어떤 것"은 무엇입니까?


“유형”에 관한 몇 마디 


이제 TypeScript의 기능에 대한 힌트를 얻게 되었습니다. 모든 것이 유형을 중심으로 이루어집니다. 이것들은 String, Object, Boolean 등과 같은 고전적인 JavaScript“유형”이 아닙니다. TypeScript는 다른 유형과 마찬가지로 자체적으로 더 많은 유형을 추가합니다.


특히 "any"는 "느슨한" TypeScript 유형입니다. 의미 :이 변수는 string, boolean, object와 같은 유형 일 수 있습니다. 정말 상관하지 않습니다. 실제로 유형 검사가 전혀 없는 것과 같습니다. strict을 true로 설정하면 TypeScript에“내 코드에서 모호성을 허용하지 않습니다”라고 말합니다.


따라서 모든 오류를 처음에 수정하기가 더 어려울지라도 TypeScript의 최대 엄격도를 유지하는 것이 좋습니다. 이제 우리는 TypeScript가 실제로 작동하는 것을 볼 준비가 되었습니다!


초보자를 위한 TypeScript 자습서 : 작동 중인 TypeScript 


모든 것은 합법적 인 (명백하게) JavaScript 함수 인 filterByTerm으로 시작합니다. 프로젝트 폴더에 filterByTerm.js라는 새 파일을 작성하고 다음 코드를 복사하십시오.

  1. function filterByTerm(input, searchTerm) {
  2. if (!searchTerm) throw Error("searchTerm cannot be empty");
  3. if (!input.length) throw Error("input cannot be empty");
  4. const regex = new RegExp(searchTerm, "i");
  5. return input.filter(function(arrayElement) {
  6. return arrayElement.url.match(regex);
  7. });
  8. }
  9. filterByTerm("input string", "java");

지금 논리를 이해하지 않아도 걱정하지 마십시오. 해당 함수의 매개 변수와 몇 줄 후에 어떻게 사용되는지 살펴보십시오. 코드를 살펴보면 이미 문제를 발견했을 것입니다 (Java가 아닙니다).


코드를 실행하거나 Jest로 테스트하지 않고도 IDE에서 해당 기능을 확인할 수 있는 방법이 있는지 궁금합니다. 가능합니까? TypeScript는 JavaScript에 대한 정적 검사, 즉 코드가 실행되기 전에 코드의 정확성을 테스트하는 가장 좋은 도구 중 하나입니다.


따라서 TypeScript 세계로 도약하여 파일 확장자를 filterByTerm.js에서 filterByTerm.ts로 변경하십시오. 이 변경으로 코드에서 많은 오류를 발견 할 수 있습니다.

TypeScript tutorial - your first steps with TypeScript 


함수 매개 변수 아래에 빨간색 표시가 보입니까? 이제부터는 텍스트 형식으로 오류를 보여 주지만 TypeScript에서 실수를 할 때마다 IDE와 텍스트 편집기에 빨간색 선이 표시됩니다.


우리가 잘못 실행하고 있음을 확인하려면 :


npm run tsc 


오류를 살펴보십시오.

  1. filterByTerm.ts:1:23 - error TS7006: Parameter 'input' implicitly has an 'any' type.
  2. filterByTerm.ts:1:30 - error TS7006: Parameter 'searchTerm' implicitly has an 'any' type.
  3. filterByTerm.ts:5:32 - error TS7006: Parameter 'arrayElement' implicitly has an 'any' type.

빙고! TypeScript는 함수 매개 변수에“any”유형이 있다고 말하고 있습니다. TypeScript 코드에 적절한 형식 주석을 추가해야 합니다.


잠깐만요, 정말로 유형이 무엇입니까?


JavaScript의 유형과 문제점은 무엇입니까? 


JavaScript에는 유형이 있으며 문자열, 부울, 숫자, 객체 등이 있다는 것을 알기 전에 언어로 작업 한 경우. 현재 JavaScript에는 7 가지 유형이 있습니다.


  • String
  • Number
  • Boolean
  • Null
  • Undefined
  • Object
  • Symbol (part of ECMAScript 2015)

해당 목록의 모든 것은 유형인 Object를 제외하고는 "원시"입니다. 

모든 JavaScript 유형에는 문자열 및 숫자와 같이 코드에서 사용할 수 있는 해당 표현이 있습니다.


  1. var name = "Hello John";
  2. var age = 33;

JavaScript의 “문제”는 변수가 변수를 원할 때마다 유형을 변경할 수 있다는 것입니다. 예를 들어 부울은 나중에 문자열이 될 수 있습니다 (types.js라는 파일에 다음 코드 저장).

  1. var aBoolean = false;
  2. console.log(typeof aBoolean); // "boolean"
  3. aBoolean = "Tom";
  4. console.log(typeof aBoolean); // "string"

변환은 의도적 일 수 있으며 개발자는 실제로 "Tom"을 부울에 할당하려고 할 수 있지만 이러한 종류의 오류는 우연히 발생할 가능성이 높습니다.


기술적으로 말하면 JavaScript의 "유형 역동성"은 의도적이므로 JavaScript 자체에는 아무런 문제가 없습니다. JavaScript는 본격적인 엔터프라이즈 언어가 아닌 웹을 위한 간단한 스크립팅 언어로 탄생했습니다.


그러나 JavaScript가 느슨해지면 코드에 심각한 문제가 발생하여 유지 관리성이 떨어질 수 있습니다. TypeScript는 JavaScript에 강력한 유형을 추가하여 이러한 문제를 해결하는 것을 목표로 합니다. 실제로 types.js의 확장자를 types.ts로 변경하면 IDE에 TypeScript가 불평하는 것을 볼 수 있습니다.


types.ts의 컴파일은 다음을 생성합니다.


types.ts:4:1 - error TS2322: Type '"Tom"' is not assignable to type 'boolean'. 


이 지식으로 무장한 TypeScript 유형에 대해 자세히 알아 보겠습니다.


발가락을 TypeScript 유형으로 담그기 


TypeScript는 유형을 중심으로 하며 코드에 전혀 유형이 없는 것처럼 보입니다. 추가 할 시간입니다. 먼저 함수 매개 변수를 수정하겠습니다. 함수가 어떻게 호출되는지 살펴보면 두 문자열을 인수로 사용합니다.


filterByTerm("input string", "java"); 


확실합니까? 함수에 첫 번째 주석을 추가해 보겠습니다. 방법은 다음과 같습니다.


  1. function filterByTerm(input: string, searchTerm: string) {
  2. // omitted
  3. }
  4. // omitted

그게 다야! 매개 변수에 유형을 추가하여 코드를 순수 JavaScript에서 TypeScript로 마이그레이션 합니다. 그러나 코드를 컴파일 하려고 하면 :


npm run tsc 


다음과 같은 일이 발생합니다.


filterByTerm.ts:5:16 - error TS2339: Property 'filter' does not exist on type 'string'. 


TypeScript가 어떻게 당신을 안내하는지 알 수 있습니까? 필터 기능에 문제가 있습니다.


  1. function filterByTerm(input: string, searchTerm: string) {
  2. // omitted
  3. return input.filter(function(arrayElement) {
  4. return arrayElement.url.match(regex);
  5. });
  6. }

우리는 TypeScript에“입력”이 문자열이지만 나중에 코드에서 배열에 속하는 필터 메소드를 호출한다고 말합니다. 우리가 실제로 원하는 것은“ 입력”을 무언가의 배열, 아마도 문자열의 배열로 표시하는 것입니까?


이를 위해 두 가지 옵션이 있습니다. string[]이 있는 옵션 1  : 

  1. function filterByTerm(input: string[], searchTerm: string) {
  2. // omitted
  3. }

또는 원하는 경우 Array <Type> 옵션 2 : 


  1. function filterByTerm(input: Array<string>, searchTerm: string) {
  2. // omitted
  3. }

개인적으로 나는 옵션 2를 더 좋아합니다. 이제 다시 컴파일 해 봅시다 (npm run tsc). 여기 있습니다 : 


  1. filterByTerm.ts:10:14 - error TS2345: Argument of type '"input string"' is not assignable to parameter of type 'string[]'.
  2. filterByTerm("input string", "java");

TypeScript는 우리를 내버려두고 싶지 않습니다. 비난하지 말고 입력을 문자열 배열로 표시했으며 이제 문자열을 전달하려고 합니다. 쉬운 수정입니다! 대신 문자열 배열을 전달해 봅시다. 


filterByTerm(["string1", "string2", "string3"], "java"); 


그리고 지금까지 완전한 코드가 있습니다 : 


  1. function filterByTerm(input: Array<string>, searchTerm: string) {
  2. if (!searchTerm) throw Error("searchTerm cannot be empty");
  3. if (!input.length) throw Error("input cannot be empty");
  4. const regex = new RegExp(searchTerm, "i");
  5. return input.filter(function(arrayElement) {
  6. return arrayElement.url.match(regex);
  7. });
  8. }
  9. filterByTerm(["string1", "string2", "string3"], "java");

나에게 좋아 보인다. 그러나 컴파일하면 그렇지 않습니다 (npm run tsc). 


filterByTerm.ts:6:25 - error TS2339: Property 'url' does not exist on type 'string'. 


Ok TypeScript, 충분히 공평합니다. 우리는 문자열 배열을 전달하지만 나중에 코드에서 "url"이라는 속성에 액세스 하려고 합니다. 


return arrayElement.url.match(regex); 


즉, 문자열 배열이 아닌 객체 배열이 필요합니다. 다음 섹션으로 수정하겠습니다. 


초보자를 위한 TypeScript 자습서 : TypeScript 개체 및 인터페이스 


filterByTerm에 문자열 배열이 전달되었으므로 TypeScript가 불평하는 것은 놀라운 일입니다. 유형 문자열 TypeScript에 "url"속성이 없습니다. 모든 개체에 필요한 url 속성이 있는 개체 배열을 전달하여 TypeScript를 도와 드리겠습니다.


  1. filterByTerm(
  2. [{ url: "string1" }, { url: "string2" }, { url: "string3" }],
  3. "java"
  4. );

그리고 함수 서명을 업데이트하여 객체 배열을 가져옵니다.


  1. function filterByTerm(input: Array<object>, searchTerm: string) {
  2. // omitted
  3. }

이제 코드를 컴파일하자 :


npm run tsc 


출력에 감탄하십시오.


filterByTerm.ts : 6 : 25-오류 TS2339 : 'url'속성이 'object'유형에 없습니다.


다시 갑니다! 적어도 TypeScript에서는 의미가 있습니다. 일반 JavaScript 객체에는“url”이라는 속성이 없습니다. 그리고 나에게 이것은 TypeScript가 실제로 빛나기 시작하는 곳입니다.


요점은 임의의 개체에 속성을 할당하고 하루에 호출 할 수 없다는 것입니다. TypeScript는 코드의 모든 엔티티가 특정 형태를 준수 할 것을 기대합니다. 그리고 TypeScript의 모양에는 인터페이스라는 이름이 있습니다.


이제 처음에는 외계인 구문처럼 보이지만 인터페이스에 익숙해지면 어디서나 사용할 수 있습니다. 그런데 인터페이스 란 무엇입니까? TypeScript의 인터페이스는 계약과 같습니다. 또는 인터페이스가 엔티티의 "모델"과 다른 방식으로 표현하십시오.


코드를 살펴보면 모양이 다음 패턴을 따라야 하는 객체에 대해 Link라는 간단한 “모델”을 생각할 수 있습니다.

  • 문자열 유형의 url 속성이 있어야 합니다.

TypeScript에서 인터페이스와 같이 "모델"을 정의합니다 (filterByTerm.ts의 맨 위에 다음 코드를 입력하십시오).


  1. interface ILink {
  2. url: string;
  3. }

인터페이스 선언으로“지금부터 TypeScript 코드에서 해당 모양을 사용하고 싶습니다”라고 말합니다. 물론 유효한 JavaScript 구문이 아니며 컴파일 중에 제거됩니다.


팁 : TypeScript의 규칙 인 대문자 I로 인터페이스 접두사를 사용하는 것이 좋습니다.


이제 매개 변수“input”을 수정하여 인터페이스 ILink (실제로 사용자 정의 TypeScript 유형)를 사용할 수 있습니다.


  1. function filterByTerm(input: Array<ILink>, searchTerm: string) {
  2. // omitted
  3. }

이 수정으로 TypeScript는 "ILink 배열을 기대합니다"라고 해당 함수의 입력으로 말합니다. 완전한 코드는 다음과 같습니다.


  1. interface ILink {
  2. url: string;
  3. }
  4. function filterByTerm(input: Array<ILink>, searchTerm: string) {
  5. if (!searchTerm) throw Error("searchTerm cannot be empty");
  6. if (!input.length) throw Error("input cannot be empty");
  7. const regex = new RegExp(searchTerm, "i");
  8. return input.filter(function(arrayElement) {
  9. return arrayElement.url.match(regex);
  10. });
  11. }
  12. filterByTerm(
  13. [{ url: "string1" }, { url: "string2" }, { url: "string3" }],
  14. "java"
  15. );

이 시점에서 모든 오류가 사라지고 다음을 실행할 수 있습니다.


npm run tsc 


컴파일 단계는 프로젝트 폴더에 일반 JavaScript 코드와 함께 filterByTerm.js라는 파일을 생성합니다. 파일을 확인하고 TypeScript 특정 선언이 어떻게 제거되는지 확인할 수 있습니다.


"alwaysStrict"가 true로 설정되어 있기 때문에 TypeScript 컴파일러는 filterByTerm.js의 맨 위에 "엄격한 사용"을 내 보냅니다.


첫 번째 TypeScript 코드에서 훌륭합니다! 다음 섹션에서는 인터페이스를 조금 더 살펴 보겠습니다.


초보자를 위한 TypeScript 튜토리얼 : 인터페이스 및 필드 


TypeScript 인터페이스는 가장 강력한 언어 구성 중 하나 입니다. 인터페이스는 모든 개발자가 코드를 작성할 때 해당 모양을 선택하고 이를 준수 할 수 있도록 응용 프로그램 전체에서 "모델"을 형성하는 데 도움이 됩니다.


지금까지 간단한 인터페이스 인 ILink를 정의했습니다.


  1. interface ILink {
  2. url: string;
  3. }

인터페이스에 더 많은 필드를 추가하려면 블록 내부에서 필드를 선언해야 합니다.


  1. interface ILink {
  2. description: string;
  3. id: number;
  4. url: string;
  5. }

이제 ILink 유형의 개체는 새 필드를 "구현"해야 합니다. 그렇지 않으면 오류가 발생합니다. 실제로 다음을 사용하여 코드를 컴파일합니다.


npm run tsc 


TypeScript가 비명을 지릅니다.


filterByTerm.ts:17:4 - error TS2739: Type '{ url: string; }' is missing the following properties from type 'ILink': description, id 


문제는 함수의 인수에 있습니다.


  1. filterByTerm(
  2. [{ url: "string1" }, { url: "string2" }, { url: "string3" }],
  3. "java"
  4. );

TypeScript는 인수가 ILink의 Array 유형이라는 함수 선언을 보고 공제 할 수 있습니다. 따라서 해당 배열 내의 모든 객체에는 ILink 인터페이스에 정의 된 모든 필드가 있어야 합니다 (구현).


대부분 최적의 시간과는 거리가 멀다. 결국 우리는 ILink 유형의 모든 새로운 객체가 모든 필드를 가질 것인지 알 수 없습니다. 컴파일 패스를 만들려면 물음표로 인터페이스의 필드를 선택적으로 선언 할 수 있습니다.


  1. interface ILink {
  2. description?: string;
  3. id?: number;
  4. url: string;
  5. }

이제 에디터와 컴파일러 모두 괜찮습니다. 그러나 TypeScript 인터페이스는 더 많은 기능을 수행 할 수 있습니다. 다음 섹션에서는 이를 확장하는 방법을 살펴 보겠습니다. 그러나 먼저 TypeScript의 변수에 대한 간단한 메모입니다.


초보자를 위한 TypeScript 튜토리얼 : 변수 입력 


지금까지 함수 매개 변수에 유형을 추가하는 방법을 살펴 보았습니다.


  1. function filterByTerm(input: Array<ILink>, searchTerm: string) {
  2. //
  3. }

TypeScript는 이것으로 제한되지 않으며 물론 변수에 유형을 추가 할 수도 있습니다. 예제를 설명하기 위해 함수의 인수를 하나씩 추출해 봅시다. 먼저 모든 단일 객체를 추출하겠습니다.


  1. const obj1: ILink = { url: "string1" };
  2. const obj2: ILink = { url: "string2" };
  3. const obj3: ILink = { url: "string3" };

obj1, obj2 및 obj3이 ILink 유형이라고 TypeScript에 말할 수 있는 방법에 주목하십시오. "vanilla"JavaScript에서는 다음과 같이 작성합니다.


  1. const obj1 = { url: "string1" };
  2. const obj2 = { url: "string2" };
  3. const obj3 = { url: "string3" };

다음으로 다음과 같이 ILink 배열을 정의 할 수 있습니다.


const arrOfLinks: Array<ILink> = [obj1, obj2, obj3]; 


마지막으로 검색어 :


const term: string = "java"; 


완전한 코드는 다음과 같습니다.


  1. interface ILink {
  2. description?: string;
  3. id?: number;
  4. url: string;
  5. }
  6. function filterByTerm(input: Array<ILink>, searchTerm: string) {
  7. if (!searchTerm) throw Error("searchTerm cannot be empty");
  8. if (!input.length) throw Error("input cannot be empty");
  9. const regex = new RegExp(searchTerm, "i");
  10. return input.filter(function(arrayElement) {
  11. return arrayElement.url.match(regex);
  12. });
  13. }
  14. const obj1: ILink = { url: "string1" };
  15. const obj2: ILink = { url: "string2" };
  16. const obj3: ILink = { url: "string3" };
  17. const arrOfLinks: Array<ILink> = [obj1, obj2, obj3];
  18. const term: string = "java";
  19. filterByTerm(arrOfLinks, term);

알았어요 TypeScript는 JavaScript에 비해 더 장황하고 때로는 중복되어 보입니다. 그러나 시간이 지남에 따라 유형을 많이 추가할수록 코드가 더 강력 해집니다.


유형 주석을 추가하여 TypeScript가 코드의 의도를 더 잘 이해하면 할수록 나중에 더 좋을 것입니다. 그리고 개발자 경험이 급증 할 것입니다.


예를 들어, arrOfLinks가 올바른 유형 (ILink의 배열)과 연관되면 편집기는 배열의 모든 오브젝트에 ILink 인터페이스에 정의 된대로 url이라는 특성이 있음을 유추 할 수 있습니다.


TypeScript interface infer 


자, 이것이 실제로 환상적이지 않다고 말해주십시오. TypeScript에는 문자열, 배열 및 숫자 외에도 더 많은 유형이 있습니다.


booleans, tuples,“any”, never, enums이 있습니다. 시간이 지남에 따라 모든 것을 배울 수 있습니다. 궁금한 점이 있으면 기본 유형에 대한 설명서를 확인하십시오.


이제 인터페이스 확장으로 넘어 갑시다.


초보자를 위한 TypeScript 자습서 : 인터페이스 확장 


TypeScript 인터페이스는 훌륭합니다. 그러나 다른 기존 인터페이스와 거의 동일한 코드에 새로운 엔티티가 필요할 때가 올 것입니다. 다음과 같은 속성을 가진 IPost라는 새 인터페이스를 원한다고 가정하겠습니다.


  • id, number
  • title, string
  • body, string
  • url, string
  • description, string

Description, id 및 url… 이미 동일한 속성을 가진 ILink 인터페이스가 있는 것 같습니다.


  1. interface ILink {
  2. description?: string;
  3. id?: number;
  4. url: string;
  5. }

인터페이스 ILink를 재사용 할 수 있는 방법이 있습니까? TypeScript에서 우리는 속성을 새로운 인터페이스에 할당하여 인터페이스를 확장 할 수 있습니다. 예를 들어 IPost는 ILink의 일부 특성을 "상속"합니다. 키워드 확인 방법은 다음과 같습니다.


  1. interface ILink {
  2. description?: string;
  3. id?: number;
  4. url: string;
  5. }
  6. interface IPost extends ILink {
  7. title: string;
  8. body: string;
  9. }

이제 IPost 유형의 객체는 선택적 속성 설명, id, url 및 필수 속성 제목 및 본문을 갖습니다.


  1. interface ILink {
  2. description?: string;
  3. id?: number;
  4. url: string;
  5. }
  6. interface IPost extends ILink {
  7. title: string;
  8. body: string;
  9. }
  10. const post1: IPost = {
  11. description:
  12. "TypeScript tutorial for beginners is a tutorial for all the JavaScript developers ...",
  13. id: 1,
  14. url: "www.valentinog.com/typescript/",
  15. title: "TypeScript tutorial for beginners",
  16. body: "Some stuff here!"
  17. };

post1과 같은 객체가 인터페이스를 사용할 때 post1은 해당 인터페이스에 정의 된 속성을 구현한다고 말합니다. 반면에 인터페이스는 코드에서 하나 이상의 객체를 설명하는 데 사용될 때 구현됩니다.


인터페이스를 확장한다는 것은 속성을 빌리고 코드 재사용을 위해 확장하는 것을 의미합니다. 그러나 더 많은 것이 있습니다! 조만간 TypeScript 인터페이스는 기능을 설명 할 수 있습니다.


먼저 인덱싱을 살펴 보겠습니다.


초보자를 위한 TypeScript 자습서 : 인덱싱 인터 루드 


JavaScript 객체는 키 / 값 쌍의 컨테이너입니다. 간단한 객체를 상상해보십시오.


  1. const paolo = {
  2. name: "Paolo",
  3. city: "Siena",
  4. age: 44
  5. };

점 구문을 사용하여 모든 키 값에 액세스 할 수 있습니다.


console.log(paolo.city); 


또는 대괄호 구문을 사용하십시오 (배열은 특별한 종류의 객체이기 때문에 JavaScript 배열에서도 마찬가지입니다).


console.log(paolo["city"]); 


이제 키가 동적이 되어 변수에 넣고 괄호 안에서 참조 할 수 있다고 상상해보십시오.


  1. const paolo = {
  2. name: "Paolo",
  3. city: "Siena",
  4. age: 44
  5. };
  6. const key = "city";
  7. console.log(paolo[key]);

이제 다른 객체를 추가하고 둘 다 배열 안에 넣고 filterByTerm.js에서와 같이 필터 메소드를 사용하여 배열을 필터링 하겠습니다. 그러나 이번에는 키가 동적으로 전달되므로 모든 객체 키를 필터링 할 수 있습니다.


  1. const paolo = {
  2. name: "Paolo",
  3. city: "Siena",
  4. age: 44
  5. };
  6. const tom = {
  7. name: "Tom",
  8. city: "Munich",
  9. age: 33
  10. };
  11. function filterPerson(arr, term, key) {
  12. return arr.filter(function(person) {
  13. return person[key].match(term);
  14. });
  15. }
  16. filterPerson([paolo, tom], "Siena", "city");

관련 행은 다음과 같습니다.


return person[key].match(term); 


작동합니까? JavaScript는 동적 [키]로 paolo 또는 tom을 "인덱싱 가능"하는지 여부를 신경 쓰지 않기 때문입니다. 그리고 TypeScript는 어떻습니까? 이 경우 오류가 발생합니까?


다음 섹션에서 변수 키를 사용하여 filterByTerm을 보다 역동적으로 만들겠습니다.


인터페이스는 색인을 가질 수 있습니다 


filterByTerm.ts 및 특히 filterByTerm 함수로 돌아가 보겠습니다.


  1. function filterByTerm(input: Array<ILink>, searchTerm: string) {
  2. if (!searchTerm) throw Error("searchTerm cannot be empty");
  3. if (!input.length) throw Error("input cannot be empty");
  4. const regex = new RegExp(searchTerm, "i");
  5. return input.filter(function(arrayElement) {
  6. return arrayElement.url.match(regex);
  7. });
  8. }

모든 ILink에 대해 하드 코딩 된 속성 "url"을 정규식과 일치 시키기 때문에 그렇게 유연하게 보이지 않습니다. 우리는 그 속성을 역동적 인 열쇠로 만들고 싶을 수도 있습니다. 첫 번째 시도는 다음과 같습니다.


  1. function filterByTerm(
  2. input: Array<ILink>,
  3. searchTerm: string,
  4. lookupKey: string = "url"
  5. ) {
  6. if (!searchTerm) throw Error("searchTerm cannot be empty");
  7. if (!input.length) throw Error("input cannot be empty");
  8. const regex = new RegExp(searchTerm, "i");
  9. return input.filter(function(arrayElement) {
  10. return arrayElement[lookupKey].match(regex);
  11. });
  12. }

lookupKey는 동적 키이며 대체 매개 변수 인 문자열 "url"로도 기본 매개 변수가 할당됩니다. 코드를 컴파일하자 :


npm run tsc 


컴파일합니까?


  1. error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ILink'.
  2. No index signature with a parameter of type 'string' was found on type 'ILink'.

문제의 줄은 다음과 같습니다.


return arrayElement[lookupKey].match(regex); 


“인덱스 서명 없음”. 와. 반면에 JavaScript는 느슨하지만 TypeScript는 신경 쓰지 않으므로 객체 인터페이스에 색인을 추가해야 합니다. "쉬운"수정입니다.


인터페이스 ILink로 가서 색인을 추가하십시오.


  1. interface ILink {
  2. description?: string;
  3. id?: number;
  4. url: string;
  5. [index: string]: string;
  6. }

문법은 이상하지만 객체에 대한 동적 키 액세스와 비슷합니다. 즉, 문자열 유형의 색인을 통해 해당 객체의 모든 키에 액세스 할 수 있으며 이는 다시 다른 문자열을 반환합니다.


어쨌든, 첫 번째 시도는 다음과 같은 다른 오류를 표시합니다.


  1. error TS2411: Property 'description' of type 'string | undefined' is not assignable to string index type 'string'.
  2. error TS2411: Property 'id' of type 'number | undefined' is not assignable to string index type 'string'.

인터페이스의 일부 속성은 선택적이고 정의되지 않았으며 항상 문자열 유형이 아니기 때문입니다 (예 : id는 숫자).


두 가지 이상의 다른 유형 사이에 결합되는 유형을 정의하기 위한 TypeScript 구문 인 결합 유형으로 문제를 해결할 수 있습니다.


  1. interface ILink {
  2. description?: string;
  3. id?: number;
  4. url: string;
  5. [index: string]: string | number | undefined;
  6. }

다음 줄 :

[index: string]: string | number | undefined; 


index는 문자열이며 다른 문자열, 숫자 또는 정의되지 않은 값을 반환 할 수 있음을 의미합니다. 다시 컴파일을 시도하면 다른 오류가 있습니다.


  1. error TS2339: Property 'match' does not exist on type 'string | number'.
  2. return arrayElement[lookupKey].match(regex);

맞는 말이다. match 메소드는 문자열에만 작동하며 색인에서 숫자를 반환 할 가능성이 있습니다. 오류를 잘 해결하기 위해 후회하지 않고 모든 유형을 사용할 수 있습니다.


  1. interface ILink {
  2. description?: string;
  3. id?: number;
  4. url: string;
  5. [index: string]: any;
  6. }

TypeScript 컴파일러는 다시 행복합니다! 예!


이제 또 다른 기본 TypeScript 기능인 함수의 반환 유형에 주목할 차례입니다.


초보자를 위한 TypeScript 자습서 : 함수의 반환 형식 


지금까지 많은 새로운 것들이었습니다. 어쨌든 다른 TypeScript의 유용한 기능인 함수의 반환 유형을 건너 뛰었습니다.


반환 값에 유형 주석을 추가하는 것이 왜 편리한 지 이해하려면 멋진 기능을 어지럽히십시오. 원본 버전은 다음과 같습니다.


  1. function filterByTerm(
  2. input: Array<ILink>,
  3. searchTerm: string,
  4. lookupKey: string = "url"
  5. ) {
  6. if (!searchTerm) throw Error("searchTerm cannot be empty");
  7. if (!input.length) throw Error("input cannot be empty");
  8. const regex = new RegExp(searchTerm, "i");
  9. return input.filter(function(arrayElement) {
  10. return arrayElement[lookupKey].match(regex);
  11. });
  12. }

그대로 호출하면 앞에서 본 ILink 배열과 "string3"이라는 검색어를 전달하면 예상대로 객체 배열이 반환 됩니다.


  1. filterByTerm(arrOfLinks, "string3");
  2. // EXPECTED OUTPUT:
  3. // [ { url: 'string3' } ]

그러나 이제 변경된 변형을 고려하십시오.


  1. function filterByTerm(
  2. input: Array<ILink>,
  3. searchTerm: string,
  4. lookupKey: string = "url"
  5. ) {
  6. if (!searchTerm) throw Error("searchTerm cannot be empty");
  7. if (!input.length) throw Error("input cannot be empty");
  8. const regex = new RegExp(searchTerm, "i");
  9. return input
  10. .filter(function(arrayElement) {
  11. return arrayElement[lookupKey].match(regex);
  12. })
  13. .toString();
  14. }

동일한 ILink 배열과 "string3"이라는 검색어를 사용하여 지금 호출하면… [object Object]!


  1. filterByTerm(arrOfLinks, "string3");
  2. // WRONG OUTPUT:
  3. // [object Object]

문제를 발견 할 수 있습니까? 힌트 : toString 😉


함수가 예상대로 작동하지 않으므로 프로덕션 환경에 맞지 않거나 코드를 테스트하지 않으면 알 수 없습니다. 운 좋게도 TypeScript는 편집기에서 쓸 때 이러한 오류를 잡을 수 있습니다.


다음은 수정 사항입니다 (관련 부분 만).


  1. function filterByTerm(/* omitted for brevity */): Array<ILink> {
  2. /* omitted for brevity */
  3. }

그것은 어떻게 작동 하는가? 함수 본문 앞에 유형 주석을 추가하여 TypeScript가 다른 Array를 반환 값으로 예상하도록 합니다. 이제 버그를 쉽게 발견 할 수 있습니다. 지금까지의 코드는 다음과 같습니다 (변경된 버전).


  1. interface ILink {
  2. description?: string;
  3. id?: number;
  4. url: string;
  5. [index: string]: any;
  6. }
  7. function filterByTerm(
  8. input: Array<ILink>,
  9. searchTerm: string,
  10. lookupKey: string = "url"
  11. ): Array<ILink> {
  12. if (!searchTerm) throw Error("searchTerm cannot be empty");
  13. if (!input.length) throw Error("input cannot be empty");
  14. const regex = new RegExp(searchTerm, "i");
  15. return input
  16. .filter(function(arrayElement) {
  17. return arrayElement[lookupKey].match(regex);
  18. })
  19. .toString();
  20. }
  21. const obj1: ILink = { url: "string1" };
  22. const obj2: ILink = { url: "string2" };
  23. const obj3: ILink = { url: "string3" };
  24. const arrOfLinks: Array<ILink> = [obj1, obj2, obj3];
  25. filterByTerm(arrOfLinks, "string3");

이제 컴파일하십시오.


npm run tsc 


오류를 확인하십시오.


error TS2322: Type 'string' is not assignable to type 'ILink[]'. 


환상적인. 우리는 문자열이 아닌 일련의 링크를 기대하고 있습니다. 오류를 해결하려면 필터 끝에서 .toString()을 제거하고 코드를 다시 컴파일하십시오. 지금 작동합니다!


코드에 다른 보호 계층을 추가했습니다. 물론, 그 버그는 단위 테스트로 발견되었을 수 있습니다. 실제로 TypeScript는 테스트를 완전히 대체하는 것이 아니라 훌륭한 안전 계층입니다.


유형 별명으로 탐색을 계속합시다!


초보자를 위한 TypeScript 자습서 : 유형 별칭(type aliases)과 인터페이스 


지금까지 인터페이스는 객체 및 사용자 정의 유형을 설명하기 위한 도구로 보았습니다. 그러나 다른 사람의 코드를 숨기면 키워드 유형을 발견했을 수도 있습니다.


분명히 인터페이스와 유형은 TypeScript에서 상호 교환 적으로 사용되지만 여러면에서 다릅니다. 이것이 TypeScript 초보자에게 혼란의 원인입니다.


기억하십시오 : TypeScript의 인터페이스는 대부분 복잡한 객체의 형태입니다.


반면에 유형은 사용자 정의 모양을 설명하는 데 사용될 수도 있지만 별명 일 수도 있고 다른 유형으로 사용자 정의 유형의 레이블입니다. 예를 들어, 몇 개의 필드가 있는 인터페이스를 상상해 봅시다. 하나는 부울, 숫자 및 문자열의 결합 유형입니다.


  1. interface IExample {
  2. authenticated: boolean | number | string;
  3. name: string;
  4. }

예를 들어, 유형 별명을 사용하여 해당 사용자 정의 조합 유형을 추출하고 인증 된 레이블을 작성할 수 있습니다.


  1. type Authenticated = boolean | number | string;
  2. interface IExample {
  3. authenticated: Authenticated;
  4. name: string;
  5. }

이렇게 하면 변경 내용을 격리 할 수 ​​있으므로 코드베이스 전체에 공용체 유형을 복사 / 붙여 넣을 필요가 없습니다.


예제 (filterByTerm)에 유형을 적용하려면 ILinks라는 새 레이블을 작성하고 여기에 Array <ILink>를 지정하십시오. 그렇게 하면 더 긴 체계 대신 전자를 참조 할 수 있습니다.


  1. // the new label
  2. type ILinks = Array<ILink>;
  3. // the new label
  4. function filterByTerm(
  5. input: ILinks,
  6. searchTerm: string,
  7. lookupKey: string = "url"
  8. ): ILinks {
  9. if (!searchTerm) throw Error("searchTerm cannot be empty");
  10. if (!input.length) throw Error("input cannot be empty");
  11. const regex = new RegExp(searchTerm, "i");
  12. return input.filter(function(arrayElement) {
  13. return arrayElement[lookupKey].match(regex);
  14. });
  15. }
  16. const obj1: ILink = { url: "string1" };
  17. const obj2: ILink = { url: "string2" };
  18. const obj3: ILink = { url: "string3" };
  19. const arrOfLinks: ILinks = [obj1, obj2, obj3];
  20. filterByTerm(arrOfLinks, "string3");

자, 이것이 라벨링 유형의 가장 영리한 예는 아니지만 요점을 파악해야 합니다. 인터페이스와 유형 사이에 무엇을 사용해야 합니까? 복잡한 객체에 대한 인터페이스를 선호합니다. TypeScript 문서에서 제안한 접근 방식 :


이상적인 소프트웨어 속성이 확장 가능하므로 가능한 경우 항상 유형 별칭 위에 인터페이스를 사용해야 합니다. 


그것이 당신의 의심을 분명히 하는 데 도움이 되었기를 바랍니다.


다음 섹션에서는 작별 인사를 하기 전에 두 가지 TypeScript 주제를 간략하게 살펴 보겠습니다. 계속가요!


초보자를 위한 TypeScript 튜토리얼 : 인터페이스 및 객체에 대한 추가 정보 


함수는 JavaScript에서 일류 시민이지만 Object는 언어에서 가장 중요한 요소입니다.


객체는 대부분 키 / 값 쌍을위한 컨테이너이며 함수를 보유 할 수 있다는 것은 놀라운 일이 아닙니다. 함수가 객체 내부에 있으면 키워드 this를 통해 "호스트"객체에 액세스 할 수 있습니다.


  1. const tom = {
  2. name: "Tom",
  3. city: "Munich",
  4. age: 33,
  5. printDetails: function() {
  6. console.log(`${this.name} - ${this.city}`);
  7. }
  8. };

“this”에 대한 업데이트가 필요한 경우 The Little JavaScript Book의 JavaScript에서 This를 확인하십시오.


지금까지 문자열과 숫자를 설명하기 위해 TypeScript 인터페이스가 간단한 객체에 적용되는 것을 보았습니다. 그러나 그들은 더 많은 것을 할 수 있습니다. 예를 들어 봅시다. 다음 코드를 사용하여 interfaces-functions.ts라는 새 파일을 만듭니다.


  1. const tom = {
  2. name: "Tom",
  3. city: "Munich",
  4. age: 33,
  5. printDetails: function() {
  6. console.log(`${this.name} - ${this.city}`);
  7. }
  8. };

JavaScript 객체이지만 유형이 필요합니다. 잘 정의 된 모양에 맞는 톰을 만들기 위한 인터페이스를 만들어 봅시다. “IPerson”은 어떻습니까? Tom에 새로운 인터페이스를 적용 해 보자.

  1. interface IPerson {
  2. name: string;
  3. city: string;
  4. age: number;
  5. }
  6. const tom: IPerson = {
  7. name: "Tom",
  8. city: "Munich",
  9. age: 33,
  10. printDetails: function() {
  11. console.log(`${this.name} - ${this.city}`);
  12. }
  13. };

코드를 컴파일하고 (npm run tsc) 실패했는지 확인하십시오.


  1. interfaces-functions.ts:11:3 - error TS2322: Type '{ name: string; city: string; age: number; printDetails: () => void; }' is not assignable to type 'IPerson'.
  2. Object literal may only specify known properties, and 'printDetails' does not exist in type 'IPerson'.

IPerson에는 printDetails라는 속성이 없지만 더 중요한 것은 함수 여야 합니다. 운 좋게도 TypeScript 인터페이스는 함수를 설명 할 수도 있습니다. 방법은 다음과 같습니다.


  1. interface IPerson {
  2. name: string;
  3. city: string;
  4. age: number;
  5. printDetails(): void;
  6. }

여기에 함수 유형의 printDetails 속성을 추가하여 void를 반환했습니다. void는 아무것도 반환하지 않는 함수의 반환 값으로 유용합니다.


실제로 콘솔에 인쇄하는 함수는 아무것도 반환하지 않습니다. printDetails에서 문자열을 반환하는 경우 반환 유형을 문자열로 조정할 수 있습니다.


  1. interface IPerson {
  2. name: string;
  3. city: string;
  4. age: number;
  5. printDetails(): string;
  6. }
  7. const tom: IPerson = {
  8. name: "Tom",
  9. city: "Munich",
  10. age: 33,
  11. printDetails: function() {
  12. return `${this.name} - ${this.city}`;
  13. }
  14. };

이제 함수에 매개 변수가 있으면 어떻게 해야 합니까? 인터페이스에서 유형 주석을 추가 할 수 있습니다.


  1. interface IPerson {
  2. name: string;
  3. city: string;
  4. age: number;
  5. printDetails(): string;
  6. anotherFunc(a: number, b: number): number;
  7. }

IPerson을 구현하는 객체 안에“an…”을 입력하기 시작하면 대부분의 IDE가 자동으로 기능을 완성합니다. 최고의 개발자 생산성.


이 안내서에서 무엇이 누락 되었습니까? 


명백한 이유 때문에 여기서는 모든 단일 TypeScript 기능을 다룰 수 없었습니다. 예를 들어 ES2015 클래스와 인터페이스 또는 Partial과 같은 고급 유형과의 관계를 의도적으로 중단했습니다.


향후 게시물에서 더 많은 TypeScript를 다룰 수 있지만 TypeScript 문서에 대해 서두르면 공식 TypeScript 문서는 그다지 친숙하지는 않지만 내 가이드를 읽은 후에는 더 깊이 파고 드는 것이 더 쉬울 것입니다.


결론과 자료 


가이드를 읽고 읽어 주셔서 감사합니다. 이제 프로젝트에서 TypeScript를 사용할 준비가 되셨기를 바랍니다. 편리한 TypeScript 가이드가 필요하면 여기로 돌아 오거나 페이지를 즐겨 찾기에 추가하십시오.


이 TypeScript 튜토리얼에서는 다음을 배웠습니다.


  • type annotations for variables, function parameters, and return values
  • interfaces
  • custom types
  • type aliases

TypeScript가 잘못된 인수 유형에서 잘못된 반환 값에 이르기까지 바보 같은 오류에서 JavaScript 코드를 저장하는 것을 보았습니다. TypeScript가 테스트를 대체하지 않는다는 것을 반복합니다. 그것은 처음에는 이해하기 어렵지만 투자 가치가 있는 소중한 도구입니다 


TypeScript의 진화에 대한 최신 정보를 유지하려면 새로운 릴리스 및 기능에 대해 배울 수있는 공식 TypeScript 블로그를 따르는 것이 좋습니다.


TypeScript 튜토리얼을 읽은 후에도 환상적인 무료 리소스인 TypeScript 책을 사용하여 언어를 계속 탐색 할 수 있습니다.



페이지 정보

조회 142회 ]  작성일19-10-17 10:51

웹학교