TypeScript 모범 사례를 따르세요. - AWS 규범적 지침

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

TypeScript 모범 사례를 따르세요.

TypeScript 의 JavaScript 기능을 확장하는 언어입니다. 형식이 강하고 객체 지향적인 언어입니다. 를 TypeScript 사용하여 코드 내에서 전달되는 데이터 유형을 지정할 수 있으며 형식이 일치하지 않을 경우 오류를 보고할 수 있습니다. 이 섹션에서는 TypeScript 모범 사례의 개요를 제공합니다.

데이터 설명

코드에 있는 객체 및 함수의 모양을 설명하는 TypeScript 데 사용할 수 있습니다. any 유형을 사용하는 것은 변수 유형 검사를 선택 해제하는 것과 같습니다. 코드에 any를 사용하지 않는 것이 좋습니다. 다음 예를 참고하세요

type Result = "success" | "failure" function verifyResult(result: Result) { if (result === "success") { console.log("Passed"); } else { console.log("Failed") } }

enum 사용

enum을 사용하여 명명된 상수 세트를 정의하고 코드베이스에서 재사용할 수 있는 표준을 정의할 수 있습니다. 글로벌 수준에서 enum을 한 번 내보낸 다음 다른 클래스에서 해당 enum을 가져와서 사용하도록 하는 것이 좋습니다. 코드베이스에서 이벤트를 캡처할 수 있는 가능한 작업 세트를 만들고 싶다고 가정해 보겠습니다. TypeScript 숫자 기반 열거형과 문자열 기반 열거형을 모두 제공합니다. 다음 예에서는 열거형을 사용합니다.

enum EventType { Create, Delete, Update } class InfraEvent { constructor(event: EventType) { if (event === EventType.Create) { // Call for other function console.log(`Event Captured :${event}`); } } } let eventSource: EventType = EventType.Create; const eventExample = new InfraEvent(eventSource)

사용자 인터페이스

인터페이스는 클래스에 대한 계약입니다. 계약을 생성하는 경우 사용자는 계약을 준수해야 합니다. 다음 예에서는 인터페이스를 사용하여 props를 표준화하고 이 클래스를 사용할 때 호출자가 예상 파라미터를 제공하는지 확인합니다.

import { Stack, App } from "aws-cdk-lib"; import { Construct } from "constructs"; interface BucketProps { name: string; region: string; encryption: boolean; } class S3Bucket extends Stack { constructor(scope: Construct, props: BucketProps) { super(scope); console.log(props.name); } } const app = App(); const myS3Bucket = new S3Bucket(app, { name: "my-bucket", region: "us-east-1", encryption: false })

일부 속성은 객체를 처음 생성할 때만 수정할 수 있습니다. 다음 예제와 같이 속성 이름 앞에 readonly를 입력하여 이를 지정할 수 있습니다.

interface Position { readonly latitude: number; readonly longitute: number; }

인터페이스 확장

인터페이스를 확장하면 인터페이스 간에 속성을 복사할 필요가 없으므로 중복이 줄어듭니다. 또한 코드를 읽는 사람도 애플리케이션의 관계를 쉽게 이해할 수 있습니다.

interface BaseInterface{ name: string; } interface EncryptedVolume extends BaseInterface{ keyName: string; } interface UnencryptedVolume extends BaseInterface { tags: string[]; }

빈 인터페이스 사용 금지

잠재적 위험을 유발할 수 있으므로 빈 인터페이스는 피하는 것이 좋습니다. 다음 예제에는 라는 빈 인터페이스가 있습니다. BucketProps myS3Bucket1 객체와 myS3Bucket2 객체 모두 유효하지만 인터페이스가 어떠한 계약도 적용하지 않기 때문에 서로 다른 표준을 따릅니다. 다음 코드는 속성을 컴파일하고 인쇄하지만 이로 인해 애플리케이션에 불일치가 발생합니다.

interface BucketProps {} class S3Bucket implements BucketProps { constructor(props: BucketProps){ console.log(props); } } const myS3Bucket1 = new S3Bucket({ name: "my-bucket", region: "us-east-1", encryption: false, }); const myS3Bucket2 = new S3Bucket({ name: "my-bucket", });

팩토리 사용

추상 팩토리 패턴에서 인터페이스는 클래스를 명시적으로 지정하지 않고 관련 객체의 팩토리를 만드는 역할을 합니다. 예를 들어, Lambda 함수를 생성하기 위한 Lambda 팩토리를 생성할 수 있습니다. 구성 내에서 새 Lambda 함수를 생성하는 대신 생성 프로세스를 팩토리에 위임합니다. 이 디자인 패턴에 대한 자세한 내용은 Refactoring.Guru 설명서의 추상 팩토리를 참조하십시오 TypeScript.

속성에 구조 분해 사용

ECMAScript 6 (ES6) 에 도입된 디스트럭처링은 배열 또는 객체에서 여러 데이터를 추출하여 자체 변수에 할당할 수 있는 JavaScript 기능입니다.

const object = { objname: "obj", scope: "this", }; const oName = object.objname; const oScop = object.scope; const { objname, scope } = object;

표준 이름 지정 규칙 정의

이름 지정 규칙을 적용하면 코드베이스의 일관성이 유지되고 변수 이름을 지정하는 방법을 고려할 때 오버헤드가 줄어듭니다. 다음과 같이 하는 것이 좋습니다:

  • 변수 및 함수 이름에는 CamelCase를 사용합니다.

  • 클래스 이름 PascalCase 및 인터페이스 이름에 사용합니다.

  • 인터페이스 멤버에는 camelCase를 사용합니다.

  • 유형 이름 및 열거형 PascalCase 이름에 사용합니다.

  • CamelCase를 사용하여 파일 이름 지정(예: ebsVolumes.tsx 또는 storage.tsb)

var 키워드를 사용하지 마세요.

let명령문은 에서 지역 변수를 선언하는 데 사용됩니다. TypeScript 키워드와 비슷하지만 var 키워드에 비해 범위 지정에 몇 가지 제한이 있습니다. var let을 사용하여 블록에 선언된 변수는 해당 블록 내에서만 사용할 수 있습니다. var키워드는 블록 범위를 지정할 수 없습니다. 즉, 키워드는 특정 블록 (으로 {} 표시됨) 외부에서 액세스할 수 있지만 정의된 함수 외부에서는 액세스할 수 없습니다. 변수를 재선언하고 업데이트할 수 있습니다. var 키워드는 사용하지 않는 것이 좋습니다. var

ESLint와 Prettier를 사용해 보세요.

ESLint는 코드를 정적으로 분석하여 문제를 빠르게 찾아냅니다. ESLint를 사용하여 코드의 모양이나 동작 방식을 정의하는 일련의 어설션(린트 규칙이라고 함)을 생성할 수 있습니다. ESLint에는 코드 개선에 도움이 되는 자동 수정자 제안도 있습니다. 마지막으로 ESLint를 사용하여 공유 플러그인에서 린트 규칙을 로드할 수 있습니다.

Prettier는 다양한 프로그래밍 언어를 지원하는 잘 알려진 코드 포맷터입니다. 코드 형식을 수동으로 지정하지 않아도 되도록 Prettier를 사용하여 코드 스타일을 설정할 수 있습니다. 설치 후 package.json 파일을 업데이트하고 npm run formatnpm run lint 명령을 실행할 수 있습니다.

다음 예제는 프로젝트에 ESLint와 Prettier 포맷터를 활성화하는 방법을 보여줍니다. AWS CDK

"scripts": { "build": "tsc", "watch": "tsc -w", "test": "jest", "cdk": "cdk", "lint": "eslint --ext .js,.ts .", "format": "prettier --ignore-path .gitignore --write '**/*.+(js|ts|json)'" }

액세스 한정자 사용

의 private 수정자는 가시성을 동일한 클래스로만 TypeScript 제한합니다. 속성 또는 메서드에 private 한정자를 추가하면 동일한 클래스 내에서 해당 속성이나 메서드에 액세스할 수 있습니다.

public 한정자를 사용하면 모든 위치에서 클래스 속성과 메서드에 액세스할 수 있습니다. 속성 및 메서드에 액세스 한정자를 지정하지 않으면 기본적으로 public 한정자를 사용합니다.

protected 한정자를 사용하면 같은 클래스와 하위 클래스 내에서 클래스의 속성과 메서드에 액세스할 수 있습니다. 애플리케이션에서 서브클래스를 생성하려는 경우 protected 수정자를 사용하십시오. AWS CDK

유틸리티 유형 사용

유틸리티 유형은 TypeScript 기존 유형에 대한 변환 및 연산을 수행하는 미리 정의된 유형 함수입니다. 이를 통해 기존 유형을 기반으로 새 유형을 만들 수 있습니다. 예를 들어, 속성을 변경 또는 추출하고, 속성을 선택 또는 필수로 만들거나, 변경할 수 없는 버전의 유형을 만들 수 있습니다. 유틸리티 유형을 사용하면 보다 정확한 유형을 정의하고 컴파일 시 잠재적 오류를 포착할 수 있습니다.

부분 <Type>

Partial입력 유형의 모든 멤버를 선택 Type 사항으로 표시합니다. 이 유틸리티는 지정된 형식의 모든 하위 집합을 나타내는 형식을 반환합니다. 다음은 Partial의 예제입니다.

interface Dog { name: string; age: number; breed: string; weight: number; } let partialDog: Partial<Dog> = {};

필수 <Type>

Required그 반대입니다Partial. 입력 유형의 모든 멤버를 Type 선택 사항이 아닌 (즉, 필수) 로 만듭니다. 다음은 Required의 예제입니다.

interface Dog { name: string; age: number; breed: string; weight?: number; } let dog: Required<Dog> = { name: "scruffy", age: 5, breed: "labrador", weight 55 // "Required" forces weight to be defined };