함수와 메소드에 type alias 지정하는 법

|

코딩애플강의를 보고 정리했습니다.

function type

함수 타입도 type alias로 저장해서 쓰는게 가능하다.

예를들어 다음과 같이 가정한다면,

  • 숫자 두개를 파라미터로 입력가능
  • 숫자를 return 하는 함수를 별명(alias)지어서 사용한다는 가정

이런식으로 타입을 만들 수 있다.

type NumOut = (x: number, y: number) => number;

근데 이거를 이런식으로 만든타입을 함수에 집어넣으면 안된다.
(function 키워드에는 ()이거 내부랑 오른쪽에만 타입지정이 가능하기때문임)

// 이렇게는 안되고
function 함수이름 :NumOut (){}

이렇게 해줘야함

type NumOut = (x: number, y: number) => number;

let ABC: NumOut = function (x, y) {
  return x + y;
};

타입 지정에 관해서는 틀에 정해진건 없으니 type alias를 만들기 싫다면 함수 만들 때 직접 타입작성을 하면되겠다.

메소드 안에 타입 지정하기

메소드란 프로퍼티의 값으로 함수가 올 수도 있는데, 이러한 프로퍼티를 메소드(method)라고 불리운다.

let 회원정보 = {
  name: 'kim',
  age: 30,
  plusOne(x) {
    return x + 1;
  },
  changeName: () => {
    console.log('안녕');
  },
};
회원정보.plusOne(1);
회원정보.changeName();

이런 메소드에 타입을 지정해주려면 어떡해야할까?

type Member = {
  name: string,
  age: number,
  plusOne: (x: number) => number,
  changeName: () => void,
};

let 회원정보: Member = {
  name: 'kim',
  age: 30,
  plusOne(x) {
    return x + 1;
  },
  changeName: () => {
    console.log('안녕');
  },
};

회원정보.plusOne(1);
회원정보.changeName();

이렇게 해주면 되겠다.

Literal Type, as const

|

코딩애플강의를 보고 정리했습니다.

Literal Type

  • 특정 글자나 숫자만 가질 수 있게 제한을 두는 타입이다.

Ex)

// 이제 john은 '대머리'라는 글자만 할당 가능함
let john: '대머리';

// 이제 kim은 '솔로'라는 글자만 할당 가능함
let kim: '솔로';
// or기호 써도 됨
// 방향이라는 변수는 이제 left 또는 right만 할당 가능함
let 방향: 'left' | 'right';
방향 = 'left';
  • 함수도 똑같다.
  • 파라미터 선언할 때 글자나 숫자 집어넣으면 그 값만 파라미터로 넣을 수 있고,
  • return 타입선언할 때도 글자나 숫자를 집어넣으면 그 값만 return할 수 있다.
function 함수(a: 'hello'): 1 | 0 | -1 {
  return 1;
}

as const

‘kim’이라는 타입만 들어 올 수 있는 함수인데, 이렇게 하면 에러가난다.

var 자료 = {
  name: 'kim',
};

function 내함수(a: 'kim') {}
내함수(자료.name);

이유는 함수는 ‘kim’타입만 파라미터에 들어올수 있다고 해놨고,
자료.name이라는건 string 타입이지, ‘kim’타입이 아니기 때문이다.
해결방안으로는 다음이있다.

  1. object만들 때 타입을 잘 미리 정하기,
  2. assertion사용하기 (as ‘kim’)
  3. as const object 자료에 붙이기

EX)

var 자료 = {
  name : 'kim'
} as const;

function 내함수(a : 'kim') {

}
내함수(자료.name)

as const의 효과

  • 타입을 object의 value로 바꿔줌.
    (타입을 ‘kim’으로 바꿔줌)
  • object안에 있는 모든 속성을 readonly로 바꿔줌 (변경하면 에러나게끔)
    object를 잠그고 싶다면 as const를 활용해보자

타입 변수에 담기(type 키워드 써서 & readonly)

|

코딩애플강의를 보고 정리했습니다.

Type Aliases

  • 타입을 변수에 담아서 사용

  • type 타입변수명 = 타입종류

  • 관습적으로 대문자로 시작한다.

  • 재정의가 불가능하다.

type Animal = string | number | undefined;

let 동물: Animal;
  • type키워드를 유니온 타입처럼 사용 가능하다.
type Name = string;
type Age = number;
type NewOne = Name | Age;
  • 이런것도 가능 (extend)
type PositionX = { x: number };
type PositionY = { y: number };
type XandY = PositionX & PositionY;
let 좌표: XandY = { x: 1, y: 2 };

// Type alias & { name : string }도 가능

object 타입에도 적용 가능

type 사람 = {
  name: string,
  age: number,
};

let teacher: 사람 = { name: 'john', age: 20 };
  • 이렇게 물음표연산자로 속성이 undefined 라는 타입도 가질 수 있다라는거를 명시해줄수 있다.
type Square = {
  color?: string,
  width: number,
};

let 네모2: Square = {
  width: 100,
};

참고로, type 키워드를 안쓰면 이렇게 만들어야한다.

// 그리 가독성 좋은 코드는 아닌듯
let teacher: {
  name: string,
  age: number,
} = { name: 'john', age: 20 };

readonly

자바스크립트 기초를 살펴보자면, const 변수는 상수 값을 할당하는 변수이므로 재할당이되면 에러를 낸다.

const 출생지역 = 'seoul';
출생지역 = 'busan'; // 에러

하지만 예외는 있는법 const로 할당해준 오브젝트객체안의 내용은 변경이 가능하다.

const 여친 = {
  name: '엠버',
};
여친.name = '유라';

const 변수는 재할당만 막아줄뿐 그 안에 있는 object속성 바꾸는 것 까지는 관여하지 않기 때문이다.
object 속성을 바뀌지 않게 막고싶을때, readonly타입을 사용하자.

  • readonly 키워드는 속성 왼쪽에 붙일 수 있다.
  • 특정 속성을 변경불가능하게 잠궈준다.

(참고로 readonly는 컴파일시 에러를 내는 것일 뿐 변환된 js 파일 보시면 잘 바뀌긴 한다고함)

type Girlfriend = {
  readonly name : string,
}

let 여친 :Girlfriend = {
  name : '엠버'
}

여친.name = '유라' //readonly라서 에러남

타입 확정하기 Narrowing & Assertion

|

코딩애플강의를 보고 정리했습니다.

function 내함수(x: number | string) {
  return x + 1; //에러남
}

이렇게 작성을 해주면 이런 에러가난다.
Operator '+' cannot be applied to types 'string | number' and 'number'

string | number 같은 union type 에는 일반적으로 조작을 못하게 막아놔서 그런건데 이럴 경우
(간단하게 파라미터로 들어오는 x의 값이 문자일지 숫자일지 모르기때문임)

  1. 타입을 하나로 Narrowing(축소)해주거나,
  2. Assert(주장)해주거나

둘 중 하나를 해주면 된다.

Type Narrowing

if문등으로 타입을 하나로 정해주는것을 뜻한다.
다른말로 defensive하게 코딩한다 라고도 한다.

Ex)

function 내함수(x: number | string) {
  if (typeof x === 'number') {
    return x + 1;
  } else if (typeof x === 'string') {
    return x + 1;
  } else {
    return 0;
  }
}

Narrowing타입 방식에는 몇가지 알아둬야할게있다.

  • 마지막에 else{} 없으면 에러남
    (return 하지 않는 조건문이 있다면 나중에 버그가 생길 수 있어서 에러를 내줌)

  • 꼭 typeof를 쓸 필요는 없고 타입을 하나로 확정지을 수 있는 코드라면 어떤것도 Narrowing역할을 해줄 수 있다.
    (in,instanceof 등)

Type Assertion

변수명 as number

function 내함수(x :number | string){
    // 이 변수를 number라고 주장하겠다는 뜻임 하지만,
    // 이러려면 내가 함수에 무조건 숫자가 들어올 것이다 라는 사실을 알고있어야 안전하게 쓰임
    return (x as number) + 1
}
console.log( 내함수(123) );

as 키워드에는 사용시 특징이있다.

  1. as 키워드는 유니온 타입 같은 복잡한 타입을 하나의 정확한 타입으로 줄이는 역할을 수행함
    EX) (number 타입을 as string 이렇게 바꾸면 에러가난다)

  2. 타입실드 임시 해제용이다. 실제 코드 실행결과는 as있을 때나 없을 때나 거의 동일함

as를 쓰면 간편하지만 엄격한 타입체크 기능을 잠깐 안쓰겠다는 것과 동일하기때문에 다음과 같은 상황에서만 되도록이면 as를 쓰자.

  1. 왜 타입에러가 나는지 모르겠는 상황에 임시로 에러해결용으로 사용
  2. 내가 어떤 타입이 들어올지 정말 확실하게 알고 있는데 컴파일러 에러가 방해할 때

구식 assertion 문법

as 키워드 대신 <> 괄호를 사용했었다.
하지만 리액트에서 사용시 html태그와 헷갈릴 수 있어서 지금은 as키워드를 주로 사용한다.

let 이름 :number = 123;

(이름 as string) + 1;  //현재문법
<string>이름 + 1;   //옛날문법

함수에 타입 지정하는 법 & void 타입

|

코딩애플강의를 보고 정리했습니다.

함수에 타입 지정

함수는 총 두군데 타입지정이 가능하다.

  1. 함수로 들어오는 자료 (파라미터)
  2. 함수에서 나가는 자료 (return)
function test(x: number): number {
  return x * 2;
}
  • 함수로 들어오는 파라미터 타입지정은 파라미터 옆에 적으면 됨

  • 함수가 실행된 후 남는 값 (return 우측에 있는 값) 타입지정하고 싶으면 함수명() 우측에 적으면 됨

  • 파라미터에 타입을 지정하면 필수 파라미터가 된다.

// 리액트에서 예를들면..
const onClick =(e:any)=>{
....
}

// 이러면 에러남
<button onClick={()=>onClick()} />

// 이렇게 해야됨
<button onClick={(e)=>onClick(e)} />

void 타입

함수는 void 타입이 있다.
‘아무것도 없이 공허함’을 뜻하는 타입이라고 하는데, return할 자료가 없는 함수의 타입으로 사용가능하다.

EX)

function test(x: number): void {
  return x * 2; //여기서 에러남
}

이 함수에서 뭔가를 return하려고할 때 에러를 낸다.
함수에 return 방지장치를 주고 싶을 때 void 타입을 활용하자.

파라미터가 옵션일 경우

함수에 파라미터자리를 만들어놨지만 가끔 파라미터 없이 쓸 때도 있다.
그럴때 사용하자.

function test(x?: number) {}
test(); //가능
test(2); //가능

x : number | undefined 이거랑 똑같은 의미이다.
그런데 함수에서 number | undefined이거는 Union type인데, Union type을 사용하면 어떻게될까?

함수에서 Union type사용

아래와 같은 경우 에러를 낸다.

// 함수에 숫자 또는 문자를 집어넣으면 + 1 해주는 함수
function 자릿수세기(x: number | string) {
  return x + 1;
}

쌩 자바스크립트에서는 문자나 숫자 모두 +1이 가능하지만,
타입스크립트에선 변수의 타입이 number|string 이런 Union type인 경우 자료 조작을 금지 시킨다.
아직 이 파라미터의 타입이 확실하지 않으니까 파라미터 조작을 미리 방지하는거다.

function 내함수(x?: number): number {
  return x * 2;
}

이런 코드도 타입스크립트가 에러를 내는데,
x라는 파라미터는 옵션이고, 옵션인 파라미터는 number|undefined 이런식으로 타입정의가 진행된다.
그렇기 때문에, x라는 파라미터가 뭔지 확실하지 않아 에러를 낸다.

이처럼 타입스크립트는 엄격한 성격을 띄고있는데 이런 성격에 맞춰주려면 내가 코드를 엄격하게 짜주는 수 밖에 없을것 같다.