횡단 유형
type Admin = {
name: string;
privileges: string();
};
type Employee = {
name: string;
startDatae: Date;
};
// 여기
type ElevatedEmlpoyee = Admin & Employee;
const e1: ElevatedEmlpoyee = {
name: 'KIM',
privileges: ('create-server'),
startDatae: new Date()
}
interface Admin {
name: string;
privileges: string();
};
interface Employee {
name: string;
startDatae: Date;
};
interface ElevatedEmlpoyee extends Admin, Employee {}
const e1: ElevatedEmlpoyee = {
name: 'KIM',
privileges: ('create-server'),
startDatae: new Date()
}
교차 유형은 인터페이스 상속과 밀접한 관련이 있습니다.
즉, 두 코드는 정확히 동일한 작업을 수행합니다.
개체 유형은 개체 속성의 조합을 나타냅니다.
type Combinable = string | number;
type Numeric = number | boolean;
type Universal = Combinable & Numeric;
숫자 유형이 유일한 교차 유형이므로 Universal은 숫자 유형으로 간주합니다.
공용체 유형은 공통점이 있는 유형을 나타냅니다.
교차 연산자는 모든 유형과 함께 사용할 수 있으므로 이와 같이 교차 유형을 쉽게 구현할 수 있습니다.
타입 가드
타입 가드의 종류
type Combinable = string | number;
function add(a: Combinable, b: Combinable) {
// 이 조건문을 타입가드라고 함
if (typeof a === 'string' || typeof b === 'string') {
return a.toString() + b.toString();
}
return a + b;
}
위의 코드와 마찬가지로 직접 입력할 수 있습니다.
유형 가드를 사용하면 공용체 유형의 유연성을 활용하고 코드가 런타임에 올바르게 작동하는지 확인할 수 있습니다.
Typeof는 개체 유형 가드에 사용할 수 없지만 in 및 instanceof 유형 가드는 사용할 수 있습니다.
유형 보호
type Admin = {
name: string;
privileges: string();
};
type Employee = {
name: string;
startDatae: Date;
};
// 두 사용자 정의 객체 타입을 사용하여 유니언 타입을 만듬
type UnknownEmployee = Employee | Admin;
function printEmployeeInformation(emp: UnknownEmployee) {
console.log('Name: ' + emp.name); // 에러 아님
console.log('Privileges: ' + emp.privileges); // 에러
}
위의 코드에서 두 객체 모두 UnknownEmployee를 입력할 수 있으므로 name 속성에는 둘 다 포함되므로 버그가 아니지만 Privilege 속성에는 Admin만 포함되므로 유형 보호가 필요합니다.
typeof는 사용자 정의 객체 유형에 사용할 수 없으므로 in 키워드를 사용하여 해결할 수 있습니다.
function printEmployeeInformation(emp: UnknownEmployee) {
console.log('Name: ' + emp.name);
if('privileges' in emp) {
console.log('Privileges: ' + emp.privileges);
}
if('startDate' in emp) {
console.log('Start Date: ' + emp.startDate);
}
}
유형 가디언의 인스턴스
class Car {
drive() {
console.log('Driving...')
}
}
class Truck {
drive() {
console.log('Driving a truck...')
}
loadCargo(amount: number) {
console.log('Loading cargo ...' + amount)
}
}
type Vehicle = Car | Truck;
const v1 = new Car();
const v2 = new Truck();
function useVehicle(vehicle: Vehicle) {
vehicle.drive();
if (vehicle instanceof Truck) {
vehicle.loadCargo(1000);
}
}
문자열의 오류 검사는 typeguard에서 사용할 때 어려울 수 있으므로 instaceof를 사용하는 보다 강력한 방법도 있습니다.
instanceof는 순수한 JavaScript 함수이며 인터페이스에서 사용할 수 없습니다.
따라서 그것을 사용하면 개체가 클래스를 기반으로 하는지 확인할 수 있고 클래스를 기반으로 하는 경우 이 메서드가 있는지 확인할 수 있습니다.
친애하는 노조
interface Bird {
// 여기
type: 'bird';
flyingSpeed: number;
}
interface Horse {
// 여기
type: 'horse';
runningSpeed: number;
}
type Animal = Bird | Horse;
function moveAnimal(animal:Animal) {
let speed;
switch (animal.type) {
case 'bird':
speed = animal.flyingSpeed;
break;
case 'horse':
speed = animal.runningSpeed;
}
console.log('Moving with speed: ' + speed);
}
위의 코드는 인터페이스를 통해 생성된 객체이기 때문에 타입 프로텍트를 사용할 수 없지만 복잡하고 경우가 많아질수록 실수하기 쉽습니다.
이때 각 인터페이스에 공통 속성(이 경우 type 속성)을 적용하고 case를 switch 문으로 구분하는 방법도 사용할 수 있습니다.
이 경우 In Type Guard와 달리 케이스에 자동 완성이 표시되므로 오류를 줄일 수 있습니다.
타자
index.html
...
<body>
<input type="text" id="user-input">
</body>
...
app.ts
const userInputELement = document.getElementById('user-input');
위와 같이 코드를 작성해도 userInputElement는 HTML에서 이 입력 태그를 인식하지 못합니다.
캐스팅은 TypeScript가 직접 인식하지 못하는 특정 유형의 값을 TypeScript에 알려줌으로써 이 문제를 해결합니다.
하나는 변환하려는 요소 앞에 무언가를 추가하거나 TypeScript에 유형을 알리려는 위치에 추가하는 것입니다.
두 가지 가능성이 있습니다.
const userInputELement = <HTMLInputElement>document.getElementById('user-input')!
;
하나는 다음을 사용하여 typecasting입니다.
const userInputELement = document.getElementById('user-input')!
as HTMLInputElement;
React JSX 구문과의 충돌을 피하기 위한 대안입니다.
변환하고자 하는 유형을 선택 후 키워드로 입력하면 됩니다.
선택 요소 끝에 있는 느낌표는 TypeScript에 이전 표현식이 null로 반환되지 않음을 알려줍니다.
이 느낌표 대신 다음과 같이 작성할 수 있습니다.
const userInputELement = document.getElementById('user-input');
if(userInputELement) {
(userInputELement as HTMLInputElement).value="Hi there!
";
}
인덱스 유형
가질 수 있는 속성 측면에서 보다 유연한 개체를 만들 수 있는 기능입니다.
interface ErrorContainer {
id: number; // 에러
(prop: string): string;
}
정확한 프로퍼티 이름도 모르고, 얼마나 많은 프로퍼티가 있는지도 모르고, 이 인터페이스를 기반으로 하는 객체에 추가되는 프로퍼티는 문자열로 해석될 수 있는 프로퍼티 이름을 가져야 한다는 것만 알고 있습니다.
이 속성의 값도 문자열이어야 합니다.
따라서 id 속성에 숫자를 할당하면 다음과 같은 오류가 발생합니다.
interface ErrorContainer {
(prop: string): string;
}
const errorBag: ErrorContainer = {
email: 'Not a valid email!
',
username: 'Must start with a capital character!
'
}
함수 과부하
동일한 함수에 대해 여러 함수 서명을 정의하는 기능.
간단히 말해, 다른 매개변수로 함수를 호출하는 여러 가지 방법을 사용하여 함수 내에서 작업을 수행할 수 있습니다.
function add(a: Combinable, b: Combinable) {
if (typeof a === 'string' || typeof b === 'string') {
return a.toString() + b.toString();
}
return a + b;
}
const result = add('Kim', 'iltae');
result.split('') // 에러
위의 코드에서 우리는 결과가 문자열이라는 것을 알지만 TypeScript는 그렇지 않습니다.
따라서 String 메서드 Split을 사용하면 다음 오류가 발생합니다.
const result = add('Kim', 'iltae') as string;
물론 이와 같은 typecasting으로 고칠 수 있지만 더 많은 코드를 소비하고 최선이 아니므로 함수 오버로딩을 사용하는 것이 좋습니다.
function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: string, b: number): string;
function add(a: number, b: string): string;
function add(a: Combinable, b: Combinable) {
if (typeof a === 'string' || typeof b === 'string') {
return a.toString() + b.toString();
}
return a + b;
}
const result = add('Kim', 'iltae');
result.split('')
TypeScript가 반환 유형 자체를 정확하게 유추할 수 없는 경우 이러한 함수에 오버로드를 작성하여 사용할 수 있습니다.
함수가 지원할 수 있는 다양한 조합에 대해 반환되는 내용을 명확히 할 수 있습니다.
선택적 연결
이것은 개체의 속성이 설정되었는지 정의되지 않았는지 확실하지 않은 중첩 데이터로 구조화를 수행할 때 사용할 수 있습니다.
const fetchedUserData = {
id: 'a1',
name: 'KIM',
job: { title: 'CEO', description: 'My own company' }
};
// 여기 여기
console.log(fetchedUserData?.job?.title);
선택적 연결 연산자는 개체 및 개체 데이터의 중첩된 속성에 대한 안전한 액세스를 제공합니다.
물음표 앞의 요소가 정의되어 있지 않으면 그 뒤에 접근하지 않습니다.
이것은 데이터가 있는지 여부를 확인하는 if 문으로 컴파일됩니다.
제로 합체
const userInput = null;
// 여기
const storedData = userInput ?? 'DEFAULT';
userInput이 null이거나 정의되지 않은 경우 “DEFAULT”를 할당하려고 함을 의미합니다.
아래 코드와 달리 이 프로세스는 다음과 같은 userInput의 잘못된 값이 아닌 null 및 정의되지 않은 값만 처리합니다.
0 또는 빈 문자열(”).
const userInput = null;
const storedData = userInput || 'DEFAULT';