일반 JS로 쓰인 코드를 타입스크립트에서 쓰고 싶을때 declare라는 키워드를 쓴다. declare로 타입을 선언하면 비로소 타입을 알리게 되는 것과 같다.
참고로, 구현이 없이 타입만 모아놓은 코드를 ambient라고 하며 declare 로 선언된 타입은 JS로 컴파일 되지 않는다.
declare로 타입을 알리는 경우는 크게 3가지로 나뉘어 진다.
namespace를 쓰면 타입을 그룹화 해서 사용할 수 있다. React안에도 declare namespace React
라고 되어있고 안에 리액트와 관련된 여러가지 타입이 명시되어있다.
declare namespace D3 {
export interface Selectors {
select: {
(selector: string): Selection;
(element: EventTarget): Selection;
};
}
export interface Event {
x: number;
y: number;
}
export interface Base extends Selectors {
event: Event;
}
}
declare var d3: D3.Base;
d.ts라는 파일안에 주로 선언한다. 이때 root에 d.ts를 만들고 module을 선언하면 전역에서 사용가능하다.
말그대로 모듈이기 때문에 import해서 다른곳에서 사용가능하다. admin 만들때 style.d.ts를 root에 만들어놓고 사용한 것도 이 때문이다.
// style.d.ts
import 'styled-components';
declare module 'styled-components' {
export interface DefaultTheme {
flexCenter: ThemedCssFunction;
flexColumn: ThemedCssFunction;
gridMax: '1440px';
/* Colours */
white: '#ffffff';
offWhite: '#F0F0F0';
}
}
// 사용부
import { DefaultTheme } from 'styled-components';
const Theme: DefaultTheme = {
/* layout */
flexCenter: css`
display: fle
}
import/export 구문없이도 전역으로 타입을 사용할 수 있게 하는 특별한 개체이다.
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX {
interface IntrinsicAttributes {
css?: CSSProp;
}
}
}
JSX라는 네임스페이스에 뭔가를 전역으로 또 추가하고 싶을때 위와같이 쓴다.
// function.d.ts
type SomeType = {
a:number,
b:string
}
declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{
[key in keyof T]: Awaited<T[key]>
}>
declare const a:SomeType
// PromiseAll.ts
const PromiseAll([1,2,Promise.resolve(3)] as const) // Promise<[1,2,number]>
함수나 변수를 declare 할 수 도 있다.