아래 예문에서 함수는 object[]를 타입이다.
매개변수도 타입을 정의해줬는데, 함수 내부에서 파라미터의 속성의 타입이 없다는 에러를 발견했을 때의 오류는 어떻게 해결해야 할까?
parameter의 타입이 object일 때
let todoItems: object[];
function completeTodo(index:number, todo:object):void {
todo.done = true;
todoItems.splice(index, 1, todo);
}
todo.done의 부분 done이 빨간 밑줄이 생기는데 속성의 타입이 없다고 한다.
이럴때는 객체의 형태를 구체적으로 타입을 정의해줘야 한다.
let todoItems: {{id:number, title: string, done: boolean}}[];
function completeTodo(index:number, todo?:{id:number, title: string, done: boolean}):void {
todo.done = true;
todoItems.splice(index, 1, todo);
}
이제 중복되는 코드 부분을 정리해보자
let todoItems: {
id:number
title: string
done: boolean
}[];
todoItems의 object부분은 다른 함수에서도 매개변수나 반환값으로도 쓰이고 있다.
이럴때는 타입별칭을 사용해서 타입을 먼저 선언해 준다.
type Todo = {
id:number
title: string
done: boolean
}
let todoItems: Todo[];
Todo를 선언하고 사용하는 곳에 Todo라고 타입을 지정해주면 된다. 또는 interface를 사용한다.
interface는 타입스크립트에서 가장 핵심이다. 이제 Todo라는 값을 이용해서 중복되는 부분을 줄여나갈 수 있다.
interface란?
인터페이스는 반복되는 타입에 대해서 하나의 interface를 만들고 사용한다. 동일한 규칙을 쓰겠다는 상호간의 약속을 의미한다.
- 객체의 스펙(속성과 속성의 타입)
- 함수의 파라미터
- 함수의 스펙(파라미터, 반환 타입)
- 배열과 객체를 접근하는 방식
- 클래스
[객체 속성과 속성의 타입]
// bin라는 변수는 User라는 interface를 받는다.
// interface User는 객체의 스펙이 정의됨
interface User{
name: string
age: number
}
const bin : User = {
age: 33,
name: '비니'
}
- 함수의 파라미터에 인터페이스 활용
함수의 인터페이스를 활용할 때 파라미터에 정의를 확인하고
함수 호출시 인자가 파라미터에 정의한 인터페이스의 규칙에도 맞는지 확인한다.
아래 getUser()함수는 User의 인터페이스를 가져야한다.
function getUser(user:User) {
console.log(user)
}
// const capt = {
// name: 'bin'
// } error
const capt = {
name: 'bin',
age: 33
}
getUser(capt)
[함수 구조에 인터페이스 활용]
함수의 전체적인 모습도 인터페이스로 정의할 수 있다.
const sumFun ={
(a: number, a:number):number
}
//화살표 함수로 사용했을 때
const sum = (a, b):sumFun => {
return a + b
}
//or
let sum: sumFun
sum = function(a, b){
return a + b
}
// 위 함수는 이런 모습이다.
sum = function(a:number, b:number):number{
return a + b
}
[배열에 인터페이스 활용]
- 인덱싱 방식을 정의하는 인터페이스
interface stringArr {
[index: number]: string
// 배열에 접근하는 방식
}
const arr:stringArr = ['a', 'b']
arr[0] = 10 //stringArr에 맞지 않음
stringArr는속성은 이름이 정해져 있지 않다.
(위에서는 임의로 index라고 넣어줌)
배열에 대한 정의를 []괄호 안에 넣고, 해당 속성의 타입을 지정해 줄 수 있다.
- 인터페이스 딕셔너리 패턴
인덱싱과 유사하다. 해당 key에 대한 타입과 속성에 대한 타입을 interface에 정의해준다.
interface StringRegexDictionary{
[key: string]: RegExp
// [속성의 이름: 속성 타입]:
}
// 정규식을 갖고 있는 객체 생성
const obj: StringRegexDictionary = {
// cssfile: 'css' 정규식이 아니기에 error발생
cssfile: /\.css$/,
jsfile: /\.js$/
}
장점?
obj에 있는 key만 forEach로 돌렸다. value는 모두 string 타입이다. 타입스크립트가 자동으로 추론을 해준다.
Object.keys(obj).forEach((value) => {
console.log(value) //string
})
만일 객체에 접근했을 때 정해놓은 인터페이스에 어긋날 경우를 바로 캐치할 수 있다.
obj['cssfile'] = 'a' //RegExp타입이 아니라 오류가 나옴
[인터페이스 확장]
oop, js prototype 마찬가지로 기존의 interface를 확장해서 사용한다는 개념
interface Person2 {
name: string
age: number
}
// interface Developer {
// name: string //중복
// age: number //중복
// language: string
// }
interface Developer extends Person2{
language: string
}
- extends 키워드를 사용
확장을 하려고 할 때 이미 다른 인터페이스에 있는 속성이 중복될 경우에는
갖고 있는 속성과 타입에 대해 상속을 받아서 사용할 수 있다.
const newPerson: Developer = {
name: 'lili'
} //에러 발생
const newPerson: Developer = {
name: 'lili',
age: 33,
language: 'ts'
}
- 확장한 인터페이스로 객체를 선언
만약 하나의 속성만 사용하게 되면 인터페이스 오류가 나게 된다.
Person과 Developer의 타입들을 모두 정의 해줘야 하는것이 인터페이스 확장의 규칙이다.
'programming language > TypeScript' 카테고리의 다른 글
enum 살펴보기 (1) | 2022.12.07 |
---|---|
연산자를 이용한 타입 정의_유니온, 인터섹션 (1) | 2022.12.06 |
ts any, void (0) | 2022.12.03 |
타입스크립트 변수와 함수 타입 정의 (1) | 2022.12.03 |
tsc 컴파일 (0) | 2022.12.02 |
댓글