====== JSX ====== ===== 소개 ===== JSX는 XML 같은 구문이 포함 가능합니다. 의미는 구현에 따라 다르지만 유효한 JavaScript로 변형되어야 합니다. JSX는 React에서 인기를 얻었으나 이후 다른 애플리케이션도 볼 수 있습니다. TypeScript는 JSX를 직접 JavaScript에 포함, 타입 검사 및 컴파일할 수 있도록 지원합니다. ===== 기본 사용 방법 ===== JSX를 사용하려면 두 가지 작업을 해야 합니다. - 파일의 이름을 .tsx 확장자로 지정하세요 - jsx 옵션을 활성화하세요 TypeScript에는 세 가지 JSX 모드가 있습니다: ''preserve'', ''react'', 그리고 ''react-native''. 이 모드는 방출 단계에만 영향을 미칩니다 - 타입 검사에는 영향받지 않습니다. ''preserve'' 모드는 다른 변환 단계 (예: Babel)에서 더 사용되도록 출력의 일부로 JSX를 계속 유지합니다. 추가적으로 출력에는 ''.jsx'' 파일 확장자가 지정되어 있습니다. ''react'' 모드는 React.createElement를 방출하고 사용하기 전에 JSX 변환을 거칠 필요가 없으며 출력은 ''.js'' 파일 확장자를 갖습니다. ''react-native'' 모드는 모든 JSX를 유지하고 있다는 점에서 preserve와 같지만 대신 출력은 .js 파일 확장자를 갖습니다. ^모드 ^입력 ^출력 ^출력 파일 확장자^ |preserve |
|
|.jsx| |react |
|React.createElement("div") |.js| |react-native |
|
|.js| 이 모드는 커맨드 라인의 ''--jsx'' 명령 또는 tsconfig.json 파일의 해당 옵션을 사용하여 지정할 수 있습니다. >주의사항: React 식별자는 하드 코딩되어 있으므로 대문자 R.로 React를 사용할 수 있도록 해야 합니다. ===== as 연산자 (The as operator) ===== 타입 단언 작성 방법을 회상해봅시다. var foo = bar; 여기서 변수 bar의 타입을 foo라고 주장하고 있습니다. TypeScript도 타입 단언을 위해 꺾쇠 괄호를 사용하기 때문에 JSX의 특정 구문 파싱에는 몇가지 어려움이 있습니다. 결과적으로 TypeScript는 .tsx 파일에 꺾쇠 괄호 타입 단언을 허용하지 않습니다. 이러한 .tsx 파일의 기능 손실을 채우기 위해 새로운 타입의 단언 연산자가 추가되었습니다: as. 위 예제는 쉽게 as 연산자로 다시 작성할 수 있습니다. var foo = bar as foo; ''as'' 연산자는 ''.ts''와 ''.tsx'' 파일 모두에서 사용할 수 있으며 다른 타입 단언 스타일과 똑같이 동작합니다. ===== 타입 검사 (Type Checking) ===== JSX 타입 검사를 이해하기 위해서는 먼저 내장 요소와 값-기반 요소 사이의 차이를 이해해야 합니다. JSX 표현식 ''''이 주어지면 ''expr''은 원래 환경에 내장된 것을 참조할 수 있습니다 (예: DOM 환경의 div 또는 span) 또는 직접 작성한 사용자 정의 구성 요소를 참조할 수 있습니다. 이것이 중요한 두 가지 이유가 있습니다: - React의 경우, 내장 요소는 문자열 (React.createElement("div"))로 방출되는 반면 생성한 컴포넌트는 React.createElement(MyComponent))가 아닙니다. - JSX 요소에서 전달되는 속성의 타입은 다르게 보여야합니다. 내장 요소 속성은 본질적으로 알려져야 하는 반면에 컴포넌트는 자체 속성 집합을 지정하기를 원할 수 있습니다. TypeScript는 이러한 것들을 구분하기 위해 React와 같은 컨벤션을 사용합니다. 내장 요소는 항상 소문자로 시작하고 값-기반 요소는 항상 대문자로 시작합니다. ==== 내장 요소 (Intrinsic elements) ==== 내장 요소는 JSX.IntrinsicElements라는 특수한 인터페이스에서 볼 수 있습니다. 기본적으로 이 인터페이스가 지정되지 않으면 모든 내장 요소에 타입 검사는 하지 않습니다. 다만 이 인터페이스가 존재하는 경우, 내부 요소의 이름은 JSX.IntrinsicElements 인터페이스의 프로퍼티로서 참조됩니다. 예를 들어: declare namespace JSX { interface IntrinsicElements { foo: any } } ; // 좋아요 ; // 오류 위의 예제에서 는 잘 동작하지만 는JSX.IntrinsicElements에 지정되지 않았기 때문에 오류가 발생합니다. >참고: JSX.IntrinsicElements에서 다음과 같이 catch-all 문자열 indexer를 지정할 수도 있습니다: declare namespace JSX { interface IntrinsicElements { [elemName: string]: any; } } ===== 값-기반 요소 (Value-based elements) ===== 값 기반 요소는 스코프에 있는 식별자로 간단히 조회됩니다. import MyComponent from "./myComponent"; ; // 좋아요 ; // 오류 값 기반 요소를 정의하는 방법에는 두 가지가 있습니다: - 함수 컴포넌트(FC) - 클래스 컴포넌트 이 두 가지 유형의 값 기반 요소는 JSX 식에서 서로 구별 할 수 없으므로 첫 번째 TS는 과부하 해결을 사용하여 함수 구성 요소로 표현식을 확인하려고합니다. 프로세스가 성공하면 TS는 표현식을 해당 선언으로 해결하는 작업을 완료합니다. 값이 함수 구성 요소로 해결되지 않으면 TS는 클래스 구성 요소로 해결하려고 시도합니다. 실패 할 경우 TS는 오류를보고합니다. ===== 함수 컴포넌트(Function Component) ===== 이름에서 알 수 있듯이 컴포넌트는 첫 번째 인수가 props 객체인 JavaScript 함수로 정의됩니다. 반환 타입은 JSX.Element에 할당할 수 있도록 강제합니다. interface FooProp { name: string; X: number; Y: number; } declare function AnotherComponent(prop: {name: string}); function ComponentFoo(prop: FooProp) { return ; } const Button = (prop: {value: string}, context: { color: string }) =>