TypeScript메모_2

1. : 뒤엔 주로 타입

: 뒤에 오는건 대게는 타입이라고 인지, 그러나 경우에 따라 return도 있음

:를 사용해서 타입을 지정하는 경우는 아래의 1번이고 반환형의 타입을 지정하는 경우는 ( )뒤에 :를 사용한 2번 예제이다

1.변수or함수명:타입

2.():반환형

위의 2번의 예제

// 타입힌트
(a: number, b: number): number

// 구현예제
function add(a: number, b: number): number

2. 변수명 : person[]

해당 변수명에 person이란 타입을 가진 배열 [person,person..]이 온다는것


3. 타입명 : 타입1 & { 객체 ...}

해당 타입에 타입1,타입2를 혼합한 타입을 만듬

type Developer = Person & {
  skills: string[];
};


3.타입과 인터페이스 선언시 유의사항

; 세미콜론을 구분자로 사용함

타입을 객체 타입으로 생성시에 아래와 같은 형태가 된다
(자바스크립트의 객체와는 다르게 ;를 구분자로 사용한다 자바스크립트는 구분자,임)

type Person = {
  name: string; // 세미콜론
  age: number;
  sayHello: () => void; 
};

interface Person {
  name: string;
  age: number;
}


4.다양한 데이터타입의 배열

(데이터타입|데이터타입) 등을 사용한다 ()를 사용함

let mixedArray: (number | string)[] = [1, "two", 3, "four"];


5.함수타입

switchLocalePath: (locale?: string | undefined) => string
// 함수명 switchLocalePath 
// 매개변수 locale이라는 선택적 문자열 혹은 undefined
// 반환형 string
// 이름 있는 함수 표현식
const sum = function sum(a: number, b: number): number {
  return a + b;
};
// 이름 없는 함수 표현식
const sum = function (a: number, b: number): number {
  return a + b;
};
// 화살표 함수
const sum = (a: number, b: number): number => {
  return a + b;
};

// 리턴 생략 (중요*)
const sum = (a: number, b: number): number => a + b;

// 객체의 리턴 생략은 중괄호를 구분하기 위해서 괄호가 필요하다.
const sum = (a: number, b: number): { result: number } => ({ result: a + b });

5-1.함수타입 (실제예제 10/22추가)

// useSwitchLocalePath함수의 함수타입은 : (option?:Pick|undefiend)=>SwitchLocalePathFunction 이다

const useSwitchLocalePath: (options?: Pick<I18nCommonRoutingOptions & ComposableOptions, "router" | "route" | "i18n"> | undefined) => SwitchLocalePathFunction

예제2

6.화살표함수 표현식

// 화살표 함수를 선언하며 동시에 타입을 지정한 예제 (주로 사용)
let myFunc3 = (x: number, y: number): number => {
   return x + y;
};


7.화살표함수를 타입스크립트로 표현할때 3가지 패턴

- 일반경우

- type을 사용하는 경우 (반환형에 -> 을 사용 )

- interface를 사용하는 경우 (반환형에 : 을 사용) * 중요 / 아래의 이미지참조


8.콜백함수

const logging = function (s: string) {
   console.log(s);
};

// 1.init 함수선언 
const init = (callback: (arg: string) => void) => {
   console.log('callback start');
   callback('yes!');
   console.log('callback end');
};

init(logging);

// 2.만약 위에서 const init 뒤에 : 가 온다면 해당 변수에 선언되는 함수의 타입을 지정하는것이 됨
const init:함수타입 = 함수선언


9.오버로딩

function add(a: string, b: string): string; // 오버로드 함수 선언
function add(a: number, b: number): number; // 오버로드 함수 선언
function add(a: any, b: any): any { // 오버로드 함수 실행부 (any를 써준다)
  return a + b;
}

add('hello ', 'world~');
add(1, 2);


10.실제 프로젝트에서 함수 타입 지정예제

1.
선언
const useState: <string>(key?: string | undefined, init?: (() => string | globalThis.Ref<string>) | undefined) => globalThis.Ref<string> 
       함수명 : 함수타입(화살표)
       함수명 : 제너릭 (매개변수) => 반환형 
               *변수명생략<제너릭>(매개변수)=>실행내용 // 형식이기때문에 <>의 내용은 타입단언이 아니라 제너릭이다

호출
const locale = useState<string>('locale.i18n') // key만 전달후 init은 전달하지 않음 

2.
선언
switchLocalePath: (locale?: string | undefined) => string
           함수명 : 함수타입(화살표)
           함수명 : locale로 사용할 string을 전달한며 반환형은 문자열이다

 호출
 switchLocalePath(lang.iso)

3.
선언
const computed: <ILink[]>(getter: ComputedGetter<ILink[]>, debugOptions?: DebuggerOptions | undefined) => globalThis.ComputedRef<ILink[]> (+1 overload)

3-1.const computed:<제너릭>(매개변수)=>반환형 형식이다. 여기서 <제너릭>은 해당 함수안에서 다뤄지는 데이터 타입을 표시한다
3-2.computed라는 함수에 (getter라는 함수와 debugOptions이라는 객체를 가진다) 반환형으로는 ComputedRef를 반환한다
3-3.구체적으로 보기위해서는 해당 함수의 docs를 보는게 가장 빠르다..

호출
const lists = computed<ILink[]>(() => [  { id: 1, title: 'Pinia Store', url: 'pinia', icon: 'i-carbon-store' }])

// 이 부분이 getter의 function이다
() => [  { id: 1, title: 'Pinia Store', url: 'pinia', icon: 'i-carbon-store' }]

11.타입단언 ( as )

var foo = {};
foo.bar = 123; // 오류: 속성 'bar'가 `{}`에 존재하지 않음
foo.bas = 'hello'; // 오류: 속성 'bar'가 `{}`에 존재하지 않음

interface Foo {
    bar: number;
    bas: string;
}
var foo = {} as Foo; // 1.{}을 Foo타입이라고 단언한다 
foo.bar = 123;       // 2.에러안남
foo.bas = 'hello';

var foo: any;
var bar = <string> foo; // 3.꺽쇠를 변수명앞에 사용하면서 타입단언을 할수있음 // 이제 bar의 타입은 "문자열"입니다


12.타입단언꺽쇠제너릭의 꺽쇠의 차이 예제

꺾쇠 <> 기호를 변수명, 함수명 앞에다 쓰면 '타입 단언' 이 되게 된다.

따라서 제네릭을 구현하려면 변수명, 함수명 뒤에다가 꺾쇠 괄호를 적어주어야 한다.

// 1.타입단언 (변수앞)
let value: any = "Hello, TypeScript!";
let strLength: number = (<string>value).length;

// 2.제너릭 (변수뒤)
function identity<T>(arg: T): T {
  return arg;
}
let stringValue: string = "Hello, TypeScript!";
let result: string = identity<string>(stringValue);

// 3.제너릭 (생략된 변수명 뒤)
// *변수명생략*<제너릭>(매개변수)=>반환형
const computed: <string>(getter: ComputedGetter<string>, debugOptions?: DebuggerOptions | undefined) => globalThis.ComputedRef<string> (+1 overload)


13.제너릭을 함수타입에서 사용하는 예제

function logText<T>(text: T): T {
  return text;
}
// 1과 2는 같은 의미
// #1
let str: <T>(text: T) => T = logText;
// #2
let str: {<T>(text: T): T} = logText;  // 1. {}으로 감싸고 :를 기준으로 T를 리턴해준다 = 아래의 GenericLogTextFn인터페이스와 같다
                                       // 앞선 7번의 내용을 참조 

interface GenericLogTextFn {
  <T>(text: T): T;  // 2.  ':'  를 기준으로 T를 return해준다. 또한 interface에 유효함
}
function logText<T>(text: T): T {
  return text;
}
let myString: GenericLogTextFn = logText; // 3.함수타입의 인터페이스를 사용한 예제


14.type과 interface차이

1.선언방식
// 객체형태 (그렇지만 세미콜론이 있다)
interface Person {
   name: string;
}
// 변수할당
type Person = {
   name: string
}

2.확장방식
// extends사용
interface Person {
   name: string
}
interface kim extends Person {
   age: number
}
 // & 사용
type Person = {
   name: string
}
type kim = Person  & {
   age: number
}

3.선언적확장
interface A {
  title: string;
}

interface A {
  content: string
}

// 같은 interface 명으로 A를 다시 만든다면, 자동으로 확장이 된다.(인터페이스만 가능)
interface A {
  title: string;
  content: string;
}

4.type은 computed value로 좀 더 유연하게 사용가능
// 타입
type names = 'firstName' | 'lastName';
type NameTypes = {
  [key in names]: string;  // computed value
}
const person: NameTypes = { firstName: 'sitaname', lastName: 'myoji' };

// 인터페이스 (에러)
interface NameInterface {
  [key in names]: string; // error
}

computed property name은 표현식(expression)을 이용해 객체의 key 값을 정의하는 문법이다.
type의 경우, computed property name을 사용한 타입 선언이 가능하지만, interface의 경우는 불가능이다.

5.타입스크립트 제작팀에서는 interface의 사용을 권하고 있다(확장의 용이성)


15.실제 예제 (제너릭)

제너릭으로 해당 함수내부에서 해당 제너릭의 함수를 사용한다는걸 알수있다는 점이 중요

1.타입상세
const computed: {
    <T>(getter: ComputedGetter<T>, debugOptions?: DebuggerOptions | undefined): globalThis.ComputedRef<T>;
    <T>(options: WritableComputedOptions<T>, debugOptions?: DebuggerOptions | undefined): WritableComputedRef<...>;
}
2.호출
computed<타입>(getter함수)
computed<string>(()=>'aa');

1.vue의 computed의 내용이다
2.computed안에 인터페이스로 2개의 함수타입이 아래의 형식으로 저장되어있다
{ 매개변수: 반환형, .. }
3.T를 선언해줄 경우 computed함수 내부에서 매개변수, 반환형에서 해당 타입을 사용한다는것을 알수있다
4.제너릭으로 해당 함수내부에서 해당 제너릭의 함수를 사용한다는걸 알수있다는 점이 중요



16.제너릭함수 선언 예제

아래의 형태로 자주 사용된다

const 함수명 = <T>(a: T, b: T): T[] => { 선언할 함수내용 }

// 1.일반적으로 제너릭으로 함수선언을 하는 예제
function toArray<T>(a: T, b: T): T[] {
   return [a, b];
}

// 2.제너릭 함수선언을 한줄로 표시하여 함수선언 ( *** 자주 사용되는 사례 *** )
const toArray2 = <T>(a: T, b: T): T[] => { ... }

toArray<number>(1, 2); // 숫자형 배열
toArray<string>('1', '2'); // 문자형 배열


17.함수타입을 정의한 예제

// menu라는 props를 전달한다
// 1.해당 menu props의 타입이 함수다
// 2.함수는 AwesomeLayoutPageNavbarMenuDropdownItem나 AwesomeLayoutPageNavbarMenu를 반환하는 함수이다
// 3.함수는 Object를 상속하므로 Object as ()=>반환형으로 사용된다 
// 4.as는 타입의 단언형

const props = defineProps({  
   menu: {
    type: Object as () =>
      | AwesomeLayoutPageNavbarMenuDropdownItem
      | AwesomeLayoutPageNavbarMenu,
    required: true,
  },})

18.제너릭함수선언 및 제너릭함수타입 정의 예제

const 함수명 = <T>(a: T, b: T): T[] => { 선언할 함수내용 } // 함수 선언시(한줄) // 함수타입선언이 아니라 함수선언임

const 함수명: <T>(a: T, b: T ): T[]; // 함수타입 선언시(한줄)

interface 인터페이스명 { <T>(a: T, b: T): T[]; }// 인터페이스로 함수타입 선언시 (콤마로 매개변수와 반환형 구분함)

type Person = { sayHello: () => void; }; // 타입으로 함수타입 선언시 (=>로 매개변수와 반환형 구분함)

type Person = () => void; //타입으로 함수타입 선언시




참조

코딩악마님의 제너릭강의

타입스크립트의 함수표현시

타입스크립트의 함수표현시2(인파님)

type과interface차이

타입스크립트 제너릭 (인파님)

Oct 1, 2023 Views 148