
const names = ['Alice', 'Bob'];
console.log(names[2].toUpperCase());
tsconfig.json 파일로도 가능하다noImplicitAny 와 strickNullChecksnoImplicitAny : 변수들이 미리 정의된 타입을 가져야 하는지 여부 제어strickNullChecks: null과 undefined가 모든타입에서 허용 되는지 확인하는 설정타입 스크립트 컴파일러는 두가지 역할을 독립적으로 수행
독립적으로 수행되기때문에 타입오류가 있는 코드도 컴파일이 가능하다
interface Square {
width: number;
}
interface Rectangle extends Square {
height: number;
}
type Shape = Square | Rectangle;
function calculateArea(shape: Shape) {
if (shape instanceof Rectangle) {
// 'Rectangle' only refers to a type,
// but is being used as a value here
return shape.width * shape.height;
// Property 'height' does not exist
// on type 'Shape'
} else {
return shape.width * shape.width;
}
}
interface,type은 제거된다.그래서 명확하게 하기 위해서는 아래 코드와 같이 런타임에 타입 정보를 유지하는 방법이 필요합니다 .
1. 속성 체크
interface Square {
width: number;
}
interface Rectangle extends Square {
height: number;
}
type Shape = Square | Rectangle;
function calculateArea(shape: Shape) {
if ('height' in shape) {
shape; // Type is Rectangle
return shape.width * shape.height;
} else {
shape; // Type is Square
return shape.width * shape.width;
}
}
interface Square {
kind: 'square';
width: number;
}
interface Rectangle {
kind: 'rectangle';
height: number;
width: number;
}
type Shape = Square | Rectangle;
function calculateArea(shape: Shape) {
if (shape.kind === 'rectangle') {
shape; // Type is Rectangle
return shape.width * shape.height;
} else {
shape; // Type is Square
return shape.width * shape.width;
}
}
class Square {
constructor(public width: number) {}
}
class Rectangle extends Square {
constructor(public width: number, public height: number) {
super(width);
}
}
type Shape = Square | Rectangle; // 타입으로 참조
function calculateArea(shape: Shape) {
if (shape instanceof Rectangle) { // shape instanceof Rectangle 값으로 참조
shape; // Type is Rectangle
return shape.width * shape.height;
} else {
shape; // Type is Square
return shape.width * shape.width; // OK
}
}
interface LightApiResponse {
lightSwitchValue : boolean;
}
async function setLight(){
const response = await fetch('/light');
const result : LightApiResponse = await response.json();
setLightSwitch(result.lightSwitchValue);
}
function setLightSwitch(value: boolean) {
switch (value) {
case true:
turnLightOn();
break;
case false:
turnLightOff();
break;
default:
console.log(`I'm afraid I can't do that.`);
}
}
lightSwitchValue의 값이 boolean이 아니라 문자열이라면 default가 발생하게 됩니다.Typescript에서는 런타임타입과 선언된타입이 맞지 않을 수 있습니다.function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a, b) {
return a + b;
}
interface Vector2D {
x: number;
y: number;
}
function calculateLength(v: Vector2D) {
return Math.sqrt(v.x * v.x + v.y * v.y);
}
interface NamedVector {
name: string;
x: number;
y: number;
}
const v: NamedVector = { x: 3, y: 4, name: 'Zee' };
calculateLength(v); // OK, result is 5
//NamedVector를 위한 calculateLength를 구현할 필요가 없음
interface Vector2D {
x: number;
y: number;
}
function calculateLength(v: Vector2D) {
return Math.sqrt(v.x * v.x + v.y * v.y);
}
interface NamedVector {
name: string;
x: number;
y: number;
}
interface Vector3D {
x: number;
y: number;
z: number;
}
function calculateLengthL1(v: Vector3D) {
let length = 0;
for (const axis of Object.keys(v)) {
const coord = v[axis];
// 타입 호환때문에 v[axis]의 타입은 어떤 속성이 될 지 모르기때문에 number라고 확정지을 수 없음
// 따라서 coord는 any type
length += Math.abs(coord);
}
return length;
}
const vec3D = {x: 3, y: 4, z: 1, address: '123 Broadway'};
calculateLengthL1(vec3D); // OK, returns NaN
테스트를 작성할때는 구조적 타이핑이 유리합니다
interface Author {
first: string;
last: string;
}
interface DB {
runQuery: (sql: string) => any[];
}
function getAuthors(database: DB): Author[] {
const authorRows = database.runQuery(`SELECT FIRST, LAST FROM AUTHORS`);
return authorRows.map(row => ({first: row[0], last: row[1]}));
}
any는 타입 안정성이 떨어진다.any는 함수 시그니처를 무시해 버린다.any타입은 언어 서비스가 적용되지 않는다.아래와 같이 자동완성으로 속성이 나타나지 않는다.

any타입은 코드 리팩터링때 버그를 감춥니다.interface ComponentProps {
onSelectItem: (item: any) => void;
}
function renderSelector(props: ComponentProps) { /* ... */ }
let selectedId: number = 0;
function handleSelectItem(item: any) {
selectedId = item.id;
}
renderSelector({onSelectItem: handleSelectItem});
handleSelectItem의 매개변수 item이 any로 설정했기때문에 id의 유무에 상관없이 문제가 없다고 할것입니다.
하지만 id의 값이 존재하지 않는다면 타입체커를 통과함에도 불구하고 런타임에는 오류가 발생할 것입니다.
만약 any가 아닌 구체적인 타입을 사용했다면, 타입체커가 오류를 발견했을 것입니다.
요즘은 왜 글이 안 올라오나여?