- TypeScript는 JS의 static type checker(코드 실행 없이, error를 detect)임
- TypeScript는
Typed Superset of JS
(JS 코드를 그대로 오류 없이 실행 가능)- 실무에서 많은 경우의 오류 원인에 해당하는 type(일종의 올바른 틀, 규격)을 미리 정의해 둠으로써, 이로 인한 오류 발생 가능성과 디버깅 수고를 줄일 수 있음
https://www.typescriptlang.org/docs/handbook/intro.html
https://medium.com/jspoint/typescript-type-system-81fdb84bba75
1. Explicit Type Annotation ** : 변수나 인자의 type을 직접 정의/ 컴파일 통해 js로 변환되면 모두 사라짐
function greet(person: string, date: Date) { console.log(`Hello ${person}, today is ${date.toDateString()}!`); } greet("Maddison", Date()); //Argument of type 'string' is not assignable to parameter of type 'Date'.
2. Infer Types** : 자동으로 type을 인식도 가능/ type system이 추론하는 Type이 동일하다면 굳이 annotation 하지 X
let msg = "hello there!"; // ^ = let msg: string
3. TypeScript는 JS의 typeof로 확인할 수 있는,
string
,number
,boolean
등을 동일하게 포함하며, 특별한 type인any
를 더 포함함 (type을 규정하지 않고, type system도 추론할 수 없을때는 defalut로any
를 할당4. Union Type
: 여러 타입의 종류 중 하나로 표현할 경우 사용
function printId(id: number | string) { console.log("Your ID is: " + id); } // OK printId(101); // OK printId("202"); // Error printId({ myID: 22342 }); /// => Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'. Type '{ myID: number; }' is not assignable to type 'number'.
function printId(id: number | string) { console.log(id.toUpperCase()); // => Property 'toUpperCase' does not exist on type 'string | number'. Property 'toUpperCase' does not exist on type 'number'. } //위 처럼 하면 안됨(toUpperCase()가 number일 경우는 에러가 뜨므로)
// 아래 처럼 수정하면 OK function printId(id: number | string) { if (typeof id === "string") { // In this branch, id is of type 'string' console.log(id.toUpperCase()); } else { // Here, id is of type 'number' console.log(id); } }
5. Type Aliases
: 타입을 체크해야하는 변수가 여러번 반복되는 경우, 직접 정의하는 type annotation 보다 더 큰 묶음 변수에 할당하여 활용
type Point = { x: number; y: number; }; // Exactly the same as the earlier example function printCoord(pt: Point) { console.log("The coordinate's x value is " + pt.x); console.log("The coordinate's y value is " + pt.y); } printCoord({ x: 100, y: 100 });
6. Interfaces
: Type Alias와 유사
: 유일한 차이점은 type alias는 새로운 property 추가하기 위한 re-open 불가하지만, Interface는 확장가능(..extends..
통한 new property 추가 가능)interface Point { x: number; y: number; } function printCoord(pt: Point) { console.log("The coordinate's x value is " + pt.x); console.log("The coordinate's y value is " + pt.y); } printCoord({ x: 100, y: 100 });
7. Type Assertions
: value의 type에 대한 정보를 더 정확히 정의하고 싶을 때 활용
: 원래 ts 컴파일러가 인식하는 타입과 다른 값으로 지정하고자 할 때 활용 (only compile time, not runtime)
: 예를들어, 아래의 경우, TS는 단지 어떤 HTMLElement를 반환하는 정보를 가지고 있으므로, 구체적으로 사용하고자 하는 Element 종류를 정의할 수 있음const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
or
// .tsx 파일에 코드가 있는 경우는 제외 const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
8. Literal Types
: 일반적인 type들 이외에, 구체적인 값으로 type을 정의 가능
: let이 아니라 const로 변수를 정의해야 타입이 아닌 구체적 값으로 인식가능
function printText(s: string, alignment: "left" | "right" | "center") {
// ...
}
printText("Hello, world", "left");
printText("G'day, mate", "centre");
//=>Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.
function compare(a: string, b: string): -1 | 0 | 1 {
return a === b ? 0 : a > b ? 1 : -1;
}
Function Component에서 props와 return 값에 대한 type 지정
// Declaring type of props - see "Typing Component Props" for more examples type AppProps = { message: string; }; /* use `interface` if exporting so that consumers can extend */ // Easiest way to declare a Function Component; return type is inferred. const App = ({ message }: AppProps) => <div>{message}</div>; // you can choose annotate the return type so an error is raised if you accidentally return some other type const App = ({ message }: AppProps): JSX.Element => <div>{message}</div>; // you can also inline the type declaration; eliminates naming the prop types, but looks repetitive const App = ({ message }: { message: string }) => <div>{message}</div>;
useState에서는 대부분 type inference가 잘 작동
const [val, toggle] = React.useState(false); // `val` is inferred to be a boolean // `toggle` only takes booleans
그러나, 초기값이 설정되어 있지 않아 inferencer가 어려운 경우, 명확히 type을 지정해줘야 함
const [user, setUser] = React.useState<IUser | null>(null); // later... setUser(newUser);
useEffect에서 사용하기 위해서는 리턴값이 function이거나
undefined
이도록 확인할 것아래의 경우, setTimeout 함수 전체가 '{}'로 싸여있어야 return type을 number가 아니도록 infer가능
function DelayedEffect(props: { timerMs: number }) { const { timerMs } = props; useEffect(() => { setTimeout(() => { /* do stuff */ }, timerMs); }, [timerMs]); // better; use the void keyword to make sure you return undefined return null; }
children
props를 명시하지 않아도 자동으로 가짐 => 필요한 경우에만 명시하는게 명확함generic
support XdefaultProps
와 작동 X
참고링크
- 대신
React.VoidFunctionComponent
orReact.VFC
를 사용하기 (18.0.0 버전 나오기 전까지 임시)
https://dev.to/kadikraman/10-tips-for-structuring-a-react-native-project-k19
https://velog.io/@velopert/create-typescript-react-component
1. TypeScript template을 통한 설치
npx react-native init MyApp --template react-native-template-typescript
- 설치완료화면
2. IOS에서 구동시켜보기
npx react-native run-ios
- 변수형태로 클래스 외부에서 클래스 내부에서 사용되는 변수의 타입을 지정해주는 방식