const a = '5'
: a: '5'
라고 추론한다.const a: string ='5'
: 타입을 지정해줬지만 오히려 이것은 잘못된 타입 지정이다. 왜냐하면 const로 선언했기 때문에 값이 바뀔 일이 없는데 오히려 '5'에서 string이라는 넓은 타입으로 타입을 지정한 꼴이 되었다.function getId(id){
return id;
}
var myId = getId('josh') // myId는 any로 추론됨
var myId2 = getId('josh') as string // myId는 string으로 추론됨
var num as number = 10; // (x)
var num = 10 as number; // (o)
var num: number = 10;
var num = 10 as string; // (x)
var num = (10 as any) as string; // (o)
const head = document.querySelector("#head");
if (head) {
head.innerHTML = "hi";
}
non null assertion 쓰면?
const head = document.querySelecotr('#head')!
head.innerHTML = "hi";
non null assertion은 최대한 쓰지말자 (타입 에러는 해결되지만 실행 에러는 미리 방지하지 못한다.)
만약에 다른 개발자가 html코드에서 id head를 header로 바꾸면 어떻게 될까?
function numOrStr(a: number | string){
(a as number).toFixed(2); // 위험한 코드임. a가 number라고 TS를 안심시키는 행위.
}
**numOrStr('123.1111');** // 에러난다. 타입스크립트를 number라고 안심시켰지만, 결국 문자열이기 때문에 런타임에서 에러가 난다.
**numOrStr(123.1111);**
function numOrStr(a: number | string) {
if (typeof a === "number") {
console.log(a.toFixed(2));
} else if (typeof a === "string") {
console.log(a.charAt(2));
}
}
numOrStr(123.1111);
numOrStr("123.1111");
function numObjOrNumArr(a: number[] | object) {
if (Array.isArray(a)) {
console.log(a.concat(4));
} else {
Object.entries(a).forEach(([key, value]) => {
console.log(key, value);
});
}
}
numObjOrNumArr({ one: 1, two: 2, three: 3 });
numObjOrNumArr([1, 2, 3]);
class A {
aaa() {}
}
class B {
bbb() {}
}
function aOrB(param: A | B) {
if (param instanceof A) {
param.aaa();
}
}
aOrB(new A());
type B = { type: "e"; eee: string };
type F = { type: "f"; fff: string };
type G = { type: "f"; ggg: string };
function typeCheck(a: E | F | G) {
if (a.type === "e") {
console.log(a.eee);
} else {
if ("fff" in a) {
console.log(a.fff);
} else {
console.log(a.ggg);
}
}
}
interface Cat {
meow: number;
}
interface Dog {
bow: number;
}
function isDog(a: Cat | Dog): a is Dog {
return (a as Dog).bow !== undefined;
}
function greet(animal: Cat | Dog) {
if (isDog(animal)) {
console.log("개가 짖는다.");
for (let i = 0; i < animal.bow; i++) {
console.log("왈");
}
} else {
console.log("고양이가 운다");
for (let i = 0; i < animal.meow; i++) {
console.log("냐옹");
}
}
}
const isRejected = (
input: PromiseSettledResult<unknown>
): input is PromiseRejectedResult => input.status === "rejected";
const isFulfilled = <T>(
input: PromiseSettledResult<T>
): input is PromiseFulfilledResult<T> => input.status === "fulfilled";
// Promise -> Pending -> Settled(Fullfilled, Rejected)
const promises = await Promise.allSettled([
Promise.resolve("a"),
Promise.resolve("b"),
]);
const errors1 = promises.filter((a) => true);
const errors2 = promises.filter((promise) => promise.status === "rejected");
const errors3 = promises.filter(isRejected);
export {};
const errors1 = promises.filter((a) => true);
: PromiseSettledResult[] 로 추론const errors2 = promises.filter((promise) => promise.status === "rejected");
: 타입가드 안쓰면 이런식으로 코딩해야한다.const errors3 = promises.filter(isRejected);
: 타입가드를 쓰지 않으면 에러인지 성공인지 구별이 제대로 되지 않는다. 드디어 TS는 errorr3을 PromiseRejectedResult[]로 추론한다.var a: string = "hi"
var b: number = 10;
b = a; // 에러남. 'string' 형식은 'number' 형식에 할당할 수 없음
var a: string = "hi"
var b: "hi" = "hi";
b = a; // 에러남. 'string' 형식은 'hi' 형식에 해당할 수 없음
a = b; // 에러안남
interface IHero {
name: string;
}
class CHero {
name: string;
constructor(name: string) {
this.name = name;
}
}
let i: IHero;
i = new CHero("ironman");
→ 이런 코드에서 타입 에러가 발생하지 않는 이유는 타입스크립트의 ‘구조적 타이핑’ 특성 때문이다type A= {name: string}
type B = {age: number}
type C = {name: string, age: number}
type A= {name: string}
type B = {age: number}
type C = A | B // C는 D보다 넓은타입
type D = A & B // D는 C보다 좁은 타입
// D는 C보다 좁은타입
// D의 타입을 가진 d에 C의 타입을 가진 c를 대입.
// 즉 좁은 타입에 넓은 타입을 대입하여 에러가 남.
const c: C = {name: 'zerocho'}
const d: D = c
// C는 D보다 넓은 타입
// C의 타입을 가진 c에 D의 타입을 가진 d를 대입.
// 즉 넓은 타입에 좁은 타입을 대입하여 에러가 나지 않음.
const d: D = {name: 'eunsu', age: 25}
const c: C = d
const d:D = {name: 'zerocho', age: 29, married: false} -> 에러남
// 넓은 타입에 좁은 타입 대입하면 에러 안난다며 ?!!
const obj = {name: 'zeorcho', age: 29, married: false}
const d:D = obj; // 에러 안남