제로초_타입스크립트2

nevermind·2023년 12월 11일
0

typescript

목록 보기
12/12
  • Array === number[]
  • forEach타입
    interface Array<T> {
    	foreach(callbackfn: (value:T, index:number, array:T[]) => void, thisArg?:any
    : void}; //T들이 같이 타입으로 정해짐
    
    [1,2,3].forEach((value)=> value);
    ['1','2','3'].forEach((value)=> value);
    
    // 각각 타입을 안써도 제네릭으로 인하여 타입을 알아챈다.
    //Array<number|string|boolean> 이렇게 쓰면 안되나?
    //그러면 타입이 다른 애들에 대한 처리가 달라진다 ex)add('1',2)
    • 연습(만들기)
      interface Arr {
          forEach(callbackFn:(item:number|string)=>void):void;
      }
      const a:Arr = [1,2,3];
      a.forEach((item)=>console.log(item))
      const b:Arr = ['1','2','3'];
      b.forEach((item)=>console.log(item))

    • 제네릭쓰기
      interface Arr<T> {
          forEach(callbackFn:(item:T)=>void):void;
      }
      const a:Arr<number> = [1,2,3];
      a.forEach((item)=> item.toFixed(1))
      const b:Arr<string> = ['1','2','3'];
      b.forEach((item)=>console.log(item))
  • map 타입
    map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
    
    [1,2,3].map((value)=> value.toString()); 
    //결과가 string으로 변하기에 유추하면 U는 string
    • 연습(만들기)

      interface Arr<T> { 
      //interface Arr<T,S>는 못한다
      //S에 타입을 지정해버리면 다른 타입에 해당되는 함수를 사용하지 못함
      //그래서 map을 사용할 때, S 제네릭을 추가하여 새로운 것을 받도록
          map<S>(callback:(v:T,i:number)=> S):S[];
      }
      const a:Arr<number> = [1,2,3];
      const b = a.map((item)=> item+1)
      const c = a.map((v)=> v.toString());
    • 위치 주의

      • add(1,2) as로 강제로 타입변환
      • add(1,2) 타입 파라미터 넣어준 것
    • 형식 조건자여야한다 === 커스텀 타입가드여야함

  • filter타입
    //1번 인터페이스
    filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
    //2번 인터페이스
    filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
    filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
    //제네릭으로 타입을 지정하거나 커스텀 타입 가드하면 S에 대한 지정이 한번 더 들어감
    
    filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
    //데이터가 [1,2,'3',4,'5']이렇게면 T에 (string|number[])로 들어가게 됨
    //1번 예제
    const filtered1 = ['1',2].filter((value)=>typeof value === 'string');
    => 이렇게 하면 문제없음, 타입추론이 정확히 되지 않지만 2번 인터페이스 사용
    => 타입은 이렇게 됨 const filtered1: (string | number)[]
    
    //2번 예제
    const filtered2 = ['1',2].filter<string>((value)=>typeof value === 'string');
    => <string>으로 선언한 순간 1번 인터페이스를 따라야함
    => 콜백함수의 반환 타입을 명시해야함
    
    //3번 예제 (2번 예제 개선)
    const filtered3 = ['1',2].filter<string>((value): value is string => typeof value === 'string');
    => 타입가드로 반환 타입 지정해줘야함
  • 공변성, 반공변성
    • return 값 - 넓은 타입으로 대입됨

      
      function a(x:string) : number {
      	return +x
      };
      type B = (x:string) => number|string;
      const b:B = a //가능
      //return값은 더 넓은 타입으로 대입이 가능하다
      
      function a(x:string) : number|string { 
      //(x:string)=>string되는 경우가 있기에
      	return +x
      };
      type B = (x:string) => number;
      const b:B = a //가능
      //b('abc') B타입에서 문제없음
      //b(123) 
      //return값은 더 넓은 타입으로 대입이 불가
    • 매개변수 : 좁은 타입으로 대입됨

      function a(x:string|number) : number {
      //(x:string)=> number 또는 (x:number) => number
      //매개변수는 위와 같이 생각하면 안됨
      //x:string|number 이 둘을 하나로 봄, 매개변수는 좁은 타입으로 대입됨
      	return 0
      };
      
      type B = (x:string) => number;
      const b:B = a //가능
  • 오버로딩
    • filter처럼 타이핑 한가지 방식 못하겠다 싶을때

    • 여러가지 케이스 써서 오버로딩하면 됨

      interface Add{
      	{x:number, y:number} : number;
      	{x:string, y:string} : string;
      }
      
      const add: Add = (x:any, y:any)=> x+y;
      //any써도 됨, 오버로딩에서 알아서 걸러서 씀
  • 에러처리법
    interface CustomError{
    	name: string;
    	message: string;
    	stack?: string;
    	response?: {
    		data: any;
    	}
    }
    
    try{...}
    catch(error){
    	if(error instanceof CustomError){
    	const customError = error as CutomError;
    	console.error(customError.response?.data};
    	customError.response?.data 
    	}
    //customError로 안만들면 사용할 때마다 
    //error as CutomError 사용해야함
    }
    
    //여기서 instanceof CustomError를 사용할때, 
    //interface가 js에서 사라지면서 CustomError를 못찾음
    //그럴때, js에서도 남아있으면서 인터페이스랑 비슷한 역할을 해주는 것이 class
    
    class CustomError extends Error{
    	response?: {
    		data: any;
    	}
    }
    //error instanceof CustomError일때는 타입가드로 좁혀졌기에
    //const customError = error as CutomError안써도 됨
    
    • as는 unknown일때 써야한다
    • 타입가드로 좁혀놨을때는 as 안써도 됨
    • 계속 유지시키고 싶을때, interface대신 class사용
    • unknown은 타입가드나 타입캐스팅이나 너가 안전하게 써, 할때 쓰임
profile
winwin

0개의 댓글