type 지정
타입으로 쓸 수 있는 것들
string, number, boolean, bigint, null, undefined,[], {}
string, number, boolean type 지정
let 문자: string = "kim";
let 숫자: number = 50;
let 참거짓: boolean = true;
// 아래와 같이 코드를 적을 시 에러메세지를 띄워준다.
let 이름 :string = 'kim';
이름 = 123;
TS -> JS 자동 변경
터미널에 아래의 코드를 입력하면 TS -> JS로 자동으로 변환해준다.
tsc -w
그다음에 html에 아래 코드를 추가한다.
<script src="index.js"></script>
array, object type 지정
array와 object 자료는 이렇게 타입지정이 가능하다.
let 배열1: number[] = [1, 2, 3];
let 배열2: string[] = ["a", "b", "c"];
let 객체1: { 사과: string; 포도: string } = { 사과: "apple", 포도: "grape" };
let 객체2: { age: number; koreaAge: number } = { age: 14, koreaAge: 16 };
or 가능하게하기 (Union type)
여러가지(or) 타입지정이 가능하다.
let 배열3: (number | string)[] = [1, "a", 2, "b"];
// type 키워드를 변수에 담아서 사용가능하다.
type nameType = number | string
let 이름 :nameType = 'kim';
특정 글자나 숫자로 type지정하기 (literal type)
특정 글자나 숫자만 가질 수 있게 제한을 두는 타입을 literal type이라고한다.
type NameType = 'kim' | 'park;
let 이름 :NameType = 'kim'; // "kim"과 "park"만 들어갈 수 있다.
//특정한 값만 나오도록하는 함수
function 함수(a : 'hello') : 1 | 0 | -1 {
return 1
}
as const 문법
밑의 코드에서 자료.name은 "kim"임에도 불구하고 에러를 낸다.
왜냐하면 "kim"이라는 type일 경우에만 에러를 안내는데
자료.name은 "kim"이 나와서 string type임으로 에러를 낸다.
"kim" type !== "string" type
let 자료 = {
name : 'kim'
}
function 내함수(a : 'kim') {
}
내함수(자료.name) // 에러
이런걸 해결하고 싶으면
1. object 만들 때 타입을 잘 미리 정하든가
2. 예전에 배웠던 assertion을 쓰시든가 (as 'kim' 이런걸 붙이는거다.)
3. 아래의 코드처럼 as const 라는걸 애초에 object 자료에 붙일 수 있다.
var 자료 = {
name : 'kim'
} as const;
function 내함수(a : 'kim') {
}
내함수(자료.name)
as const는 효과가 2개인데
1. 타입을 object의 value로 바꿔줍니다. (타입을 'kim'으로 바꿔줍니다)
2. object안에 있는 모든 속성을 readonly로 바꿔줍니다 (변경하면 에러나게)
함수에서 type 설정
함수의 파라미터와 return 값에 어떤 타입일지 지정가능하다.
1. 함수로 들어오는 자료 (파라미터)
2. 함수에서 나가는 자료 (return)
function 함수명(x :number) :number{
return x * 2
}
지금 변수의 타입이 확실하지 않으면 마음대로 연산할 수 없다.
항상 타입이 무엇인지 미리 체크하는 narrowing 또는 assertion 문법을 사용해야 허락해준다.
//에러
//타입스크립트는 확실한 걸 좋아해서 x값이 확실히 number일때만 에러창을 안 띄운다.
function 함수명(x :number | string) {
return x * 2
}
//가능
function 함수명(x :number | string) {
if (typeof x === 'number'){
return x * 2
}
}
함수 - void타입
void는 "아무것도 없이 공허함"을 뜻하는 타입인데 return을 넣으면 에러를 낸다.
return 방지 장치라고 생각하면 된다.
//에러
function 내함수(x :number) :void {
return x * 2
}
파라미터가 옵션일 경우
함수에 파라미터를 없이 사용할 때도 있는데 이럴때 이 파라미터는 옵션이다. 라고 정의 해야 에러가 안난다.
?표시는 사실 x : number | undefind와 같은거다
// 에러
function 내함수(x :number) {
return x * 2
}
내함수(); // 파라미터에 아무것도 안 넣으면 에러난다.
// 올바른 함수
// 파라미터를 옵션으로 넣으려면 ?를 추가하면된다.
function 내함수(x? :number) {
return x * 2
}
//위 코드와 같다.
function 내함수(x :number | undefind) {
return x * 2
}
객체안에 있는 함수
화살표함수를 사용하면된다.
type MathObj {
plus : (a:number, b:number) => number,
minus : (a:number, b:number) => number
}
let 오브젝트 :MathObj = {
plus(a,b){
return a + b
},
minus(a,b){
return a - b
}
}
array 순서 포함 type설정
array자료안에 순서를 포함해서 어떤 자료가 들어오는지 지정할 수 있다.
type Member = [number, boolean];
let john:Member = [100, false]
type이 선택사항일 경우
object 타입의 정의가 너무 길면 type을 변수에 담아 사용가능하다.
특정 속성이 선택사항이면 물음표를 기입가능합니다.
type MyObject = {
name? : string,
age : number
}
let 철수 :MyObject = {
name : 'kim',
age : 50
}
한꺼번에 type 지정
object속성에 하나하나 type을 설정하기 어렵다면 한꺼번에 타입지정도 가능하다.
type MyObject = {
[key :string] : number,
}
let 철수 :MyObject = {
age : 50,
weight : 100,
}
any타입
아무거나 넣어도된다. 경고문을 안 띄어준다.
이거 쓰는 순간 타입스크립트 사용하는 이유가 없다.
타입관련 버그가 나도 잡아주지 않는다.
let 이름 : any = 123
any대신에 unknown을 사용하기도 한다.
모든 자료형을 허용해주지만 버그가 나도 잡아준다.
let 나이 :unknown = 1;
나이 + 1
// 이런거 버그로 잡아준다.
// 타입스크립트는 엄격한거 좋아해서 같은 타입만 + 가능
내가 조작할 변수의 타입이 무엇인지 확실하게 체크하는 narrowing 또는 assertion 스킬이 중요하다.
사실 타입스크립트 사용하면 타입스크립트가 타입을 자동으로 부여해준다.
let 이름 = 'kim';
let 나이 = 20;
// 커서 올려보면 확인가능
타입 확정하기 Narrowing & Assertion
typescript는 타입이 명확해야한다.
그래서 아래의 코드에서 x가 number인지 string인지 확실하지 않아서 에러를 낸다.
function 내함수(x :number | string){
return x + 1 //에러남
}
두 가지 방법으로 타입을 명확하게 만들 수 있다.
if문으로 타입을 축소하는 Type Narrowing
if문을 통해서 이 type이면 이렇게 이 type이면 저렇게 해달라는게 Narrowing이다.
귀찮긴해도 부작용을 막는데 아주 탁월하다.
그리고 if문 사용시 else{}없으면 return 하지않는 조건문이 있다면 나중에 버그가 생길 수 있어서 에러가 난다.
tsconfig.js파일에 "noImplicitReturns": false,를 추가해주면 에러가 안나긴하는데 그냥 else를 잘 쓰자.
function 내함수(x :number | string){
if (typeof x === 'number') {
return x + 1
}
else if (typeof x === 'string') {
return x + 1
}
else {
return 0
}
}
타입실드를 해제시키는 Type Assertion, as키워드
이 변수의 타입은 number라고 생각해주세요~
라고 해주는게 Type Assertion이다.
as키워드를 사용하여 적용하는데
변수명 as type명 이렇게 사용한다.
// x는 number라고 생각해주세요~ 라고 코드가 말해준다.
function 내함수(x :number | string){
return (x as number) + 1
}
as는 실제로 타입을 변경해주는게 아니고 단지 타입실드를 해제시켜 에러를 알 내는것 뿐이다.
그래서 아래의 코드처럼 x를 number로 안 바꾸어주고 string + string이 된다.
function 내함수(x :number | string){
return (x as number) + 1
}
내함수("123") // "1231"
as 쓰면 간편해쥬금 하지만 정확히 코드짜려면 narrowing을 쓰자.
그래서 as 문법은 이럴 때 쓰도록 합시다.
1. 왜 타입에러가 나는지 정말 모르겠는 상황에 임시로 에러해결용으로 사용하거나
2. 내가 어떤 타입이 들어올지 정말 확실하게 알고 있는데 컴파일러 에러가 방해할 때
타입을 변수에 담아 쓰자 type키워드(alias 문법) & readonly
코드를 짜다보면 type설정이 길어져서 더러워보이는 경우가 있다.
그럴때! type키워드를 사용해서 type을 변수에 담아쓸 수 있다.
type키워드는 대문자로 쓴다.
// type이 let이나 const처럼 변수에 담는 역할을 해준다.
type Animal = string | number | undefined;
let 동물 :Animal;
// object타입에 저장할 때 특히 편하다.
type 사람 = {
name : string,
age : number,
}
let teacher :사람 = { name : 'john', age : 20 }
type 합치기 "|", "&"
or 연산자를 통해 type을 합칠 수 있다
type Name = string;
type Age = number;
type NewOne = Name | Age;
객체를 합칠 수도 있다.
그땐 &을 사용해서 합칠 수 있다
type PositionX = { x: number };
type PositionY = { y: number };
type XandY = PositionX & PositionY
let 좌표 :XandY = { x : 1, y : 2 }
readonly
const 변수에 대해 보면 변수자체는 변경이 불가능하지만 객체안에 있는 값은 변경이 가능하다.
type과 readonly를 사용하면 객체안의 있는 값도 변경이 안된다.
//const 변수지만 에러안남
const 여친 = {
name : '엠버'
}
여친.name = '유라';
// readonly사용시
type Girlfriend = {
readonly name : string,
}
let 여친 :Girlfriend = {
name : '엠버'
}
여친.name = '유라' //readonly라서 에러남
Object에 타입 지정할 때 interface문법이라는 것도 있다.
object에 타입 지정할때 type키워드가 아닌 interface문법을 사용할 수 있다.
대부분 비슷하지만 type보다 interface가 좀 더 유연하다.
interface 기본적인 사용법
type과 거의 비슷하다.
1. 대문자로 작명하고 2. { } 안에 타입을 명시해주면 된다.
(콤마 대신 세미클론도 사용가능하다)
interface Square {
color :string,
width :number,
}
let 네모 :Square = { color : 'red', width : 100 }
extends 문법
다른 interface를 복붙해서 가져오겠다는 뜻이다.
아래의 코드에서는 name이 중복되니 extends를 통해서 가져와 사용하고 있다.
// 두개의 interface에서 중복되는 name 존재
interface Student {
name :string,
}
interface Teacher {
name :string,
age :number,
}
// 위 코드와 동일하다.
interface Student {
name :string,
}
interface Teacher extends Student {
age :number
}
type 키워드와 다른 점
extends 대신에 &를 사용한다.
훨씬 간단한듯
type Animal = {
name :string
}
type Cat = Animal & { legs: number }
// Cat은 이런 type을 가진다.
Cat = {
name :string,
legs: number
}
사실 interface도 & 사용가능하다. (&를 사용하는걸 intersection라고한다.)
interface Student {
name :string,
}
interface Teacher {
age :number
}
let 변수 :Student & Teacher = { name : 'kim', age : 90 }
extends 와 &의 차이점
타입이름 중복 선언시
// interface 중복선언 가능
interface Animal {
name :string
}
interface Animal {
legs :number
}
//type 중복선언 불가능 에러남
type Animal = {
name :string
}
type Animal = {
legs :number
}
하나의 키에 type이 서로다를 경우
interface는 바로 알려주지만
type은 사용할 때 에러를 알려준다. ("never"어쩌구 뜬다.)
// interface 바로 에러 알려줌
interface Animal {
name :string
}
interface Animal {
name :number
}
//type 에러 나중에 알려줌
type Animal = {
name :string
}
type Animal = {
name :number
}
'개발 > TypeScript' 카테고리의 다른 글
타입스크립트 제네릭(Generic) 타입 (1) | 2023.10.06 |
---|---|
타입스크립트 설치법 (0) | 2023.08.14 |
타입스크립트이란 무엇인가. (0) | 2023.08.14 |
댓글