
이번 포스팅에서는 타입스크립트에서 사용하는 기본 타입을 짚고 넘어가려 합니다.

붉은색 사각형 표시가 된 타입들만 우선 짚고 넘어가겠습니다.
미리 지정해놓은 타입을 사용할 수 있습니다.
// 타입을 먼저 정의
type StringOrNumber = string | number;
// 위에서 정의된 타입으로 변수 선언
let val: StringOrNumber = 100;
어떠한 값도 가리지 않고 할당 가능
let any:any = 'any'
let bool:boolean = true
16, 10, 8, 2 진수 모두 사용가능
let number:number = 10;
'', "", `` 모두 사용 가능
let text:string = '텍스트'
let nullish:null = null
let undefineded:undefiend = undefined
자바스크립트에서 object type 은 객체, 배열, 함수 모두 아우르는 타입입니다.
타입스크립트에서도 마찬가지로 typeof 연산자가 'object'로 반환하는 모든 타입을 뜻합니다.
정확히는 number, string, boolean, bigint, symbol, null, undefined 를 제외한 모든 데이터이다.
자바스크립트의 원시타입값을 제외한 모든 값은 최상위에 언제나 object가 존재하므로 타입을 object로 지정하기는 힘든 실정입니다. 타입스크립트를 사용하는 이유와 거리가 멀어지기 때문이죠.
따라서 객체에 타입을 지정하고 싶다면, 객체 속성들에게 타입을 지정하는 방법으로 사용됩니다.
let obj: {
name: string;
age: number;
};
// 여기까지 obj 객체의 값은 undefiend 일수도있음 왜? 값을 할당 안했으니까.
obj = {
name: "태형",
age: 31,
};
//여기부턴 타입추론까지 함
이 방법은 가독성과 값의 할당 부분에 아주 큰 문제가있습니다. 그래서 인터페이스, 타입 별칭 ( type Alias ) 두 문법이 출시되었습니다.
type alias 와 interface의 변수명은 대문자로 쓰는게 암묵적인 룰입니다.
객체의 형태를 정의하는 데 사용됩니다. 이 방법은 객체가 특정 구조를 갖추고 있음을 보장합니다.
interface User {
name:string,
age:number,
weight?:number // 옵셔널 속성
}
interface Friend extends User { //인터페이스 확장
//name:string,
//age:number,
//weight?:number
FriendList:Array<string>
}
const kth = User = {
name:'김태형',
age:31,
}
타입 별칭은 특정 타입에 이름을 붙이는 데 사용됩니다. 이것은 인터페이스와 비슷하지만, 유니온이나 튜플 같은 다양한 타입을 결합할 수 있는 유연성을 제공합니다.
객체가 아닌 곳에도 사용이 가능합니다.
type User = {
name: string;
age: number;
};
const user: User = {
name: "태형",
age: 31
};
두 방식의 차이, 가능한 인터페이스를 사용하는것을 권장합니다.
확장성:인터페이스는 확장이 가능합니다. ( extends 키워드를 사용하여 다른 인터페이스를 확장할 수 있음 ) 반면, 타입 별칭은 확장할 수 없습니다.유니온과 튜플:타입 별칭은 유니온 타입이나 튜플 타입을 생성하는 데 사용할 수 있지만, 인터페이스는 그렇지 않습니다.
Array 타입은 두 가지 지정 방법이 있습니다.
let array:number[] = [1,2,3]
let array:Array<number> = [1,2,3]
Function 타입은 매개변수의 타입과 반환 타입을 설정해야합니다.
매개변수 타입 지정
// 일반 함수
function func(pram?: number) { //파라미터가 필수가 아닌경우 ? 사용가능
return "매개변수의 값: " + pram;
}
// 화살표 함수
let func = (pram: number | undefiend) => { // or 연산자
return "매개변수의 값: " + pram;
}
반환값 타입 지정
리턴쪽은 타입추론 알아서 해주긴해서 잘 안써도되지만.
// 일반 함수
function func(pram?: number) : void { //리턴값이 없음
//이경우 리턴문을 사용하면 에러가 발생한다.
}
// 화살표 함수
let func = (pram: number | undefiend) : string => { // string 타입 반환
return "매개변수의 값: " + pram;
}
Tuple 타입은 배열의 서브 타입으로 크기와 타입이 고정된 배열입니다.
//배열의 각 요소마다 타입이 지정되어있습니다.
const rgbColor:[number,number,number] = [255,255,255]
//타입뿐 아니라 값도 고정할 수 있습니다.
const rgbColor:[255,number,255] = [255,10,255]
const rgbColor2:[255,number,255] = [0,10,0] //에러를 유발합니다.
주의사항
튜플타입이 값, 타입을 고정하는것은값의 할당에만 국한되어있습니다. 배열메서드를 사용해 값을 변경하는것을 막을 수는 없습니다..
enum 타입은 특정 값 ( 상수 ) 들의 집합을 의미하며, Tuple 과 비슷하게 특정 값을 고정하는 또다른 독립된 자료형 입니다.
enum 의 반환값은 객체이며, 접근하는 방식은 배열인덱스, .접근자 둘 다 가능합니다.
특이하게도 양방향으로 매핑되어있습니다.
//배열의 각 요소마다 타입이 지정되어있습니다.
enum Os {
Window, //숫자값을 지정하지 않으면 Index 는 0부터 차례로 증가합니다.
Mac = 10, //숫자값을 지정하면 지정한 값부터 차례로 Index가 1씩 증가합니다.
Renux // Index = 11
}
enum text {
One = 'one',
Two = 'Two',
Three = 'Three'
}//생각외로 자주 쓸수도? 타입으로도 쓸 수 있다고함 잘 알아보장 ㅎㅎ..
console.log(Os) // {0: 'Window', 10: 'Ios', 11: 'Renux', Window: 0, Ios: 10, Renux: 11}
console.log(Os[10]) // Mac
console.log(Os.mac) // 10
enum은 특별한 타입이어서 자유자재로 다루기 까다롭습니다. 깊은 이해가 필요합니다.
어떠한 값을 담기위한 타입이 아니라 다른 용도로 사용되는 타입들 입니다.
함수가 리턴하는 값이 없을 때 정해지는 타입입니다. 작성하지 않고 아무것도 리턴하지 않는 함수를 만들면 void 타입으로 추론됩니다.
const func = ():void => {
return // 리턴문 작성시 에러가 발생합니다.
}
Never 타입의 용도는
const errorPrint = ():never => {
throw new Error("에러 발생");
}
const infinityLoop = ():never => {
while(true){
}
}
literal 은 말그대로 리터럴 타입입니다. 타입 선언을 생략하고 리터럴 값을 할당하게 되면, 아래와 코드와 같이 리터럴 값 그 자체가 타입이 됩니다.
const num=3; //const num: 3
let num=3; //let num: number
const text="text"//const text: "text"
let text="text"//let text: string
숫자열과 문자열만 이런 현상이 있습니다.
특이하게도 let, const 등 변수 타입에 따라 타입추론을 해주느냐 안해주느냐가 달라지네요^^..
2개 이상의 타입을 허용하는경우 이를 Union 이라고 합니다. OR 의 의미로 사용됩니다.
const stringOrNumber:string|number = 1; // 숫자와 문자열 둘 다 허용
const array:Array<string|boolean> = [true, '문자열'] //문자열, 논리값 허용
//파라미터 별 타입 지정 : 문자열 숫자 허용
const func = (value:string, returnValue:string|number):void => {
console.log(returnValue)
}
주의 사항
type Person = {
name:string;
age:number;
}
type Developer = {
name:string;
skill:string;
}
const introduce = (data: Person|Developer) => {
console.log(data.name) // 정상 작동
console.log(data.age) // 속성 없음 에러
console.log(data.skill) // 속성 없음 에러
}
위 함수에서 예측했던 방향과 결과가 다르게 작동했습니다. 이유가 무었일까요?
타입스크립트 관점에서는 introduce 함수가 호출되는 시점에 person 타입이 올지, Developer 타입이 올지 알 수 없기 때문에 에러를 내뿜게 됩니다.
즉, 타입스크립트는 어느 타입이 들어오간 간에 오류가 발생하지 않는 방향으로 확실하게 타입을 추론한다는 특성을 가졌다는 말입니다.
결과적으로 Person, Developer 두 타입이 공통적으로 보유한 name 속성만 접근할 수 있게 된것입니다.
이처럼 Union 을 이용한 타입 추론에는 어느정도 한계점이 있습니다. 아래 코드를 보시죠.
function add(x: string | number, y: string | number): string | number {
//숫자와 문자열을 더하는 모든 경우의 수를 받는 파라미터가 있습니다.
return x + y; // '+' 연산자를 'string | number' 및 'string | number' 형식에 적용할 수 없습니다.
}
add(1,2).charAt(1); // string | number' 형식에 'charAt' 속성이 없습니다.
왜 이런 에러가 발생할까요? 리턴되는 x + y 연산에 어떤 타입의 값이 오는지 예측할 수 없기때문입니다.
또한 함수를 실행하고 리턴되는 값이 어떤 값인지 추론할 수 없으니, 다른 프로토타입 함수들도 실행할 수 없게됩니다.
, intersection