π νμ μμ€ν
νμ
μμ€ν
μ νμ
μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νλ ν° μ΄μ μ€ νλλ€. νμ
μ ν΅ν΄ μμ νκ³ ν¨μ¨μ μΌλ‘ μ½λλ₯Ό μμ±ν μ μκ² λμμ£ΌκΈ° λλ¬Έμ νμ
μ€ν¬λ¦½νΈλ₯Ό μνλ€λ κ²μ μλ―Έκ° νμ¬ μΌλ§λ νμ
μ μ μ μνλμ μλ€. κ·Έλ κΈ° λλ¬Έμ μ΅λν ꡬ체μ μΌλ‘ νμ
μ μμ μνκΈ° μν΄ νμ
μμ€ν
μ λν΄ μμ보μ
π€ νμ μΆλ‘
νμ
μ€ν¬λ¦½νΈλ λλνκΈ° λλ¬Έμ μ°λ¦¬κ° μμ±ν μ½λμ λͺ
μμ μΌλ‘ μ λ¬νμ§ μμλ μ½λμ νλ¦μ ν΅ν΄ μΆλ‘ ν΄μ€λ€. const s="string"μ΄λΌλ μ½λλ₯Ό μμ±νλ©΄ μλμΌλ‘ sμλ stringνμ
μ΄ ν λΉλλ€.
const foo = {
x: [1, 2, 3], // number[]
bar: {
name: "fred",
},
}μ μμ μ xλ [1,2,3]μ λ³΄κ³ number[]μ νμ
μΌλ‘ μΆλ‘ νλ€. νμ§λ§ λ§μ½μ λ°°μ΄μ κΈΈμ΄κ° μ ν΄μ Έ μλ Tupleμ΄μλ€λ©΄ μμ νμ
μ μ΄νμ μλ¬λ₯Ό λ§λ€ μ μλ μ½λκ° λλ€.
κ·Έλμ μ΅λν ꡬ체μ μΌλ‘ νμ
μ μ ν΄μ£Όλ κ²μ΄ μ€μνλ©° λλΆλΆμ λΌμ΄λΈλ¬λ¦¬μλ μ¬μ©νλ μμ±κ³Ό λ©μλμ λν μ 보λ€μ΄ d.tsλ‘ λλλ νμΌμ μ 리λμ΄ μκΈ° λλ¬Έμ μ°Έκ³ ν μ μλ€.
[lib.es2015.core.d.tsμ Array interface]
πνμ κ³Ό μ§ν©μ κ΄κ³
μλ κ·Έλ¦Όμ ν΅ν΄ μμ²λκ² λ€μν νμ
μ΄ μ‘΄μ¬νλ κ²μ μ μ μλ€. μ΄λ¬ν νμ
μμ€ν
μ μ΄ν΄νκΈ° μν΄μ νμ
μ μ§ν©μΌλ‘ μ΄ν΄ν΄μΌ νλ€.

νμ
κ³Ό μ§ν©μ΄λΌλ... κ΄λ ¨μ΄ μμ΄ λ³΄μ΄μ§λ§, μλ°μ€ν¬λ¦½νΈμμ νλ‘ν νμ
μ λΆλͺ¨ μμ κ΄κ³κ° μλ―μ΄, νμ
λ€μλ μ§ν© κ΄κ³κ° μλ€. unknown typeμ μ μ μκΈ° λλ¬Έμ μ΄λ€ κ²μ΄λ λ€ λ μ μλ κ°μ₯ ν° μ§ν©μΌλ‘ neverλ μ΄λ€ μμλ ν¬ν¨νμ§ μλ κ°μ₯ μμ μ§ν©μΌλ‘ μ΄ν΄ν μ μλ€.
const x: never = 12 //Type 'number' is not assignable to type 'never'.unit type
νλμ κ°μ κ°λ¦¬ν€λ νμ
μ unit type λλ literal typeμ΄λΌκ³ λΆλ¦¬λ νμ
μ΄λ€. κ°μ μ§μ typeμ λͺ
μνλ€.
type A = "A"Union Type
νλκ° μλλΌ νμ
μ μ¬λ¬ κ°μ ν¨κ» λνλ΄κΈ° μν΄μ union typeμ΄ μ‘΄μ¬νλ€. union typeμ μ¬λ¬ κ°μ νμ
μ ν©ν ν©μ§ν©μΌλ‘ |μΌλ‘ λνλΈλ€.

type AB = "A" | "B"
const ab: AB = Math.random() < 0.5 ? "A" : "B"
const c: AB = "C" // Type '"C"' is not assignable to type 'AB'μ μμ μμ abλ AB μ λμ¨ νμ
μΌλ‘ λμ΄ μμ΄ "A"λ "B"κ° ν λΉλ μ μλ€. cλ ABνμ
μ μ μν "A" λλ "B"μ λΆλΆμ§ν©μ΄ μλκΈ° λλ¬Έμ μλ¬κ° λ°μνλ€. μ¦ νμ
체ν¬λ₯Ό νλ€λ κ²μ μ΄λ€ μ§ν©μ΄ λ€λ₯Έ μ§ν©μ λΆλΆμ§ν©μ΄ λ μ μλμ§ λ₯Ό νμΈνλ κ²μ΄λ€.
Intersection Type
μ¬λ¬ κ° νμ
μ λμμ λ§μ‘±νλ λΆλΆ μ§ν©, κ΅μ§ν©μ Intersection Typeμ΄λΌκ³ νλ©° &μΌλ‘ λνλΈλ€.

μ¬κΈ°μ μ΄ν΄νκΈ° μ΄λ €μ λ λΆλΆμ΄ "λ λ€ λ§μ‘±νλ€"κ³ λ§ μκ°ν΄ Union typeμ μ°¨μ΄κ° μ΄ν΄λμ§ μμμ§λ§ μ§ν©μΌλ‘ μκ°ν΄λ³΄λ μ΄ν΄κ° μ¬μ λ€. λμμ λ§μ‘±νλ€λ κ²μ λ μ§ν©μ 쑰건μ λͺ¨λ λ§μ‘±νλ€λ μλ―Έλ₯Ό κ°μ§λ€.
interface dogPerson {
loveDog: true
}
interface catPerson {
loveCat: true
}
type Both = dogPerson & catPerson
const person1: Both = {
loveDog: true,
loveCat: true,
}μ μμ μμ κ°μμ§μ κ³ μμ΄λ₯Ό λͺ¨λ μ’μνλ person1μ loveDogκ³Ό loveCatμ λͺ¨λ trueλ‘ κ°μ§κ³ μμ΄μΌ νλ€. λ λ€ λ§μ‘±νλ€λ κ²μ λ κ°μ§ typeμ λͺ¨λ λ§μ‘±ν΄μΌ νλ κ²μ μ μ μλ€.
μ§ν© κ΄κ³λ₯Ό λ€μν μμ λ₯Ό ν΅ν΄ μ’ λ μμ보μ.
keyofμ ν¨κ» μ¬μ©νλ union typeκ³Ό intersection type
interface dogPerson {
loveDog: true;
}
interface catPerson {
loveCat: true;
}
interface Both = dogPerson & catPerson;
type K = keyof (dogPerson | catPerson); // (keyof A) & (keyof B)
type T= keyof(dogPerson & catPerson) // (keyof A) | (keyof B)
const a: K = "loveDog"; // Type 'string' is not assignable to type 'never'.
const b: T = 'loveDog';Kλ ν©μ§ν©μ keyλ‘ κ΅μ§ν©μΈ never typeμ΄ λκ³ , Tλ κ΅μ§ν©μ keyμ΄κΈ° λλ¬Έμ Aμ keyμ Bμ keyμ "loveDog"|'loveDog'κ° λλ€. μ΄λΆλΆμ μμ§ μλΏμ§ μμμ κ³μν΄μ 곡λΆκ° νμν λΆλΆμΈ κ² κ°λ€.
extends
interface dogPerson {
loveDog: true
}
interface catPerson {
loveCat: true
}
interface Both extends dogPerson {
loveCat: true
}μμ intersection typeμΌλ‘ μ μνλ κ΄κ³λ₯Ό extendsλ₯Ό μ΄μ©ν΄ μμ κ΄κ³λ‘λ μ΄ν΄ν μ μλ€. λΆλͺ¨μ μμ±μ μμμ΄ μ λ¬ λ°κΈ° λλ¬Έμ μμμ subset λΆλͺ¨λ₯Ό supersetμ΄λΌκ³ λΆλ₯΄λ μ§ν© κ΄κ³μ μμ κ΄κ³κ° μΌμΉνλ κ²μ μ μ μλ€.
interface Point {
x: number
y: number
}
type PointKeys = keyof Point // "x"|"y"
function sortBy<K extends keyof T, T>(vals: T[], key: K): T[] {
// ..
return []
}
const pts: Point[] = [{ x: 1, y: 1 }]
sortBy(pts, "x") // T: Point[] K:"x"
sortBy(pts, "y") // T: Point[] K:"y"
sortBy(pts, "z") // T: Point[] K:"z" // Argument of type '"z"' is not assignable to parameter of type 'keyof Point'.μμ genericμ μ΄μ©ν μμλ₯Ό 보면 Tμλ point[]νμ
μ΄ Kμλ "x", "y", "z"κ° λ€μ΄κ°λ€. Kλ Kμ keyμ λΆλΆμ§ν©μ΄μ΄μΌνλ―λ‘ "z"λ pointμ "x"|"y" μ§ν©μ μνμ§ μκΈ° λλ¬Έμ μλ¬κ° λ°μνλ κ²μ λ³Ό μ μλ€.
β κ°κ³Ό νμ ꡬλΆνκΈ°
μλ°μ€ν¬λ¦½νΈμμλ κ°λ§ μ κ²½μ¨μ μ΄λ¦μ μ νλ©΄ λμ§λ§ νμ
μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νλ©΄μ typeμλ λ€μ΄λ°μ΄ νμν΄μ‘λ€. λ΄κ° μ μν κ²μ΄ κ°μΈμ§ νμ
μΈμ§λ₯Ό μ΄ν΄ν νμκ° μλ€.
interface Cylinder {
radius: number
height: number
}
const Cylinder = (radius: number, height: number) => ({ radius, height })
// Cannot redeclare block-scoped variable 'Cylinder'.κ°μ μ΄λ¦μΌλ‘ νμ κ³Ό κ° λͺ¨λ μ μν μ μκΈ° λλ¬Έμ ꡬλΆν μ μλ λ€μ΄λ°μ΄ νμνλ€.
interface Cylinder {
radius: number
height: number
}
function calculateVolume(shape: unknown) {
if (shape instanceof Cylinder) {
// 'Cylinder' only refers to a type, but is being used as a value here.
shape.radius
}
}λ€μ΄λ° λ¬Έμ λΏ μλλΌ νμ
μ κ°μ²λΌ μ¬μ©ν΄ μ€λ₯λ₯Ό λ§λ€κΈ°λ νλ€. instanceofλ λ°νμ μ°μ°μλ‘ κ°μ νμΈνλ€. Cylinderκ° νμ
μ΄κΈ° λλ¬Έμ μλ¬κ° λ κ²μ λ³Ό μ μλ€.
μ΄λ¬ν λ¬Έμ λ₯Ό ν΄κ²°ν μ μλ λ°©λ²μΌλ‘λ κ°κ³Ό νμ
λͺ¨λ λ μ μλ class λ₯Ό μ¬μ©ν΄ ν΄κ²°ν μ μλ€.
class Cylinder {
radius: number
height: number
}
function calculateVolume(shape: unknown) {
if (shape instanceof Cylinder) {
// 'Cylinder' only refers to a type, but is being used as a value here.
shape.radius
}
}typeof
typeofλ classμ²λΌ νμ
κ³Ό κ°μ μλ―Έλ₯Ό λͺ¨λ κ°μ§λ€. νμ
μΌλ‘ μ°μΌ λλ ν΄λΉ κ°μ νμ
μ μ½κ³ , κ°μΌλ‘ μ°μΌ λλ ν΄λΉ κ°μ νμ
μ λ¬Έμμ΄λ‘ λ°ννλ€.
const v = typeof Cylinder
console.log(v) // function
type C = InstanceType<typeof Cylinder> // Cylinder
// type InstanceType<T extends abstract new (...args: any) => any> =
// T extends abstract new (...args: any) => infer R ? R : any;μ μμ μμ typeofκ° κ°μΌλ‘ μ°μ¬ vκ° "function"λ¬Έμμ΄ κ°μΌλ‘ λ°νλμκ³ , νμ
μΌλ‘ μ°μΌ κ²½μ° Genericκ³Ό ν¨κ» μ°μ¬ Cμ νμ
μ΄ Cylinderλ‘ λμ¨ κ²μ λ³Ό μ μμλ€. μ¬κΈ°μ μ°μΈ InstanceTypeμ μ νΈλ¦¬ν° νμ
μΌλ‘ μμ±μ ν¨μ Tμ instance typeμ μλ―Ένλ€.
Branket μ κ·Όμ
μ€λΈμ νΈμ μμ± μ κ·ΌμμΈ []λ νμ
μμλ λμΌνκ² νμ
μ μμ±μ νμ
μ 보λ₯Ό μ»μ μ μλ€.
interface Person {
first: string
last: string
}
type PersonEl = Person["first" | "last"]
type Person2 = Person.first // Cannot access 'Person.first' because 'Person' is a type, but not a namespace.
type Tuple = [string, number, Date]
type TupleEl = Tuple[number]ꡬ쑰 λΆν΄ ν λΉ
ꡬ쑰 λΆν΄ ν λΉμΌλ‘ μμ£Ό μ¬μ©νλ κ²½μ°λ reactμμ μ λ¬ λ°μ propsλ₯Ό ꡬ쑰 ν λΉ λΆν΄λ‘ νμ μ λͺ μν΄ μ€ λμλ€. κΈΈμ΄μ§ μ μκΈ° λλ¬Έμ typeμ λ°λ‘ λΉΌμ μ μνλ κ² κ°λ μ±μ μ’μλ€.
type AdminDescriptionItemType = {
item: DescriptionType
name: DescriptionNameType
onDelete: (name: DescriptionNameType, id: string) => void
onChange: (name: DescriptionNameType, value: string, id: string) => void
}
export default function AdminDescriptionItem({
item,
name,
onDelete,
onChange,
}: AdminDescriptionItemType) {
// ...μλ΅
}π νμ λ¨μΈ λ³΄λ€ νμ μ μΈ
νμ λ¨μΈ (type assertion)μ μΆλ‘ ν νμ κ³Ό μκ΄μμ΄ κ°λ°μκ° μ μν νμ μ μ°μ μμλ‘ λκΈ° λλ¬Έμ μ€λ₯κ° λ°μν νλ₯ μ΄ λμμ§λ€.
interface Person {
name: string
}
const alice: Person = { name: "Alice" }
const bob = {} as Personaliceμ κ²½μ° νμ
μ μΈμ μ΄μ©ν΄ νμ
체ν¬νκΈ° λλ¬Έμ λͺ
μλ κ°μ νμ
μ΄ λ§λ μ§λ₯Ό 보μ§λ§, bobμ λ΄κ° μ μν Personμ΄λΌκ³ μ§μ νκ² λμ΄ μ€λ₯λ₯Ό λμ§μ§ μλλ€.
const alice: Person = {
name: "Alice",
occupation: "td",
} // Type '{ name: string; occupation: string; }' is not assignable to type 'Person'.
const bob = {
name: "bob",
occupation: "js",
} as Personμ΄λ²μλ Personμμ μ μν μμ± μΈμ μΆκ° μμ±μ΄ μμ λλ‘ aliceμ κ²½μ° κΈ°μ‘΄ μ μν μμ±μΈμ λ€λ₯Έ μμ±μ΄ μμμ μ€λ₯λ‘ μλ € μ£Όμ§λ§, bobμ PersonμΌλ‘ μ΄λ―Έ νμ
체ν¬λ₯Ό νλ€κ³ μ λ¬νλ κ²κ³Ό κ°μ μ€λ₯κ° μλ κ²μ λ³Ό μ μλ€.
νμ μ μΈ μ μ£Όμν μ
const people = ["alice", "bob", "jan"].map(name => ({ name })) // {name:string}[]μμ κ²½μ° νμ
μ΄ Person[]μ΄ λκΈ°λ₯Ό κΈ°λνμ§λ§ {name:string}[]λ‘ typeμ΄ μ ν΄μ§λ€. μ΄λ¬ν κ²½μ°λ 체μ΄λμ μ΄μ΄λκ° λ type μλ¬λ₯Ό λ§λ€κΈ° λλ¬Έμ νμ μμνλ νμ
κ³Ό κ°κ² λ§λ€κΈ° μν΄ μ€κ° λ¨κ³μ μμΈ‘ν νμ
μ λͺ
μν¨μΌλ‘μ¨ μ€λ₯κ° λ°μν κ³³μ λΉ λ₯΄κ² μ°Ύμλκ° μ μλ€.
const people: Person[] = ["alice", "bob", "jan"].map(
(name): Person => ({ name })
)π νμ λ¨μΈμ μΈμ μΈκΉ?
νμ λ¨μΈμ΄ νμν κ²½μ°λ λ΄κ° μ μνλ νμ μ΄ μΆλ‘ νλ νμ λ³΄λ€ λ μ νν λλ€. λΉμ°ν νμ μ€ν¬λ¦½νΈκ° λ λλνλ° λ΄κ° λ§λ€κ³ ν μ μμκΉ μΆκΈ°λ νμ§λ§ λ°νμμμ κ²°μ λλ κ²½μ° νμ μ€ν¬λ¦½νΈκ° μ κ·Όν μ μκ³ , μ΄λ―Έ μ ν΄μ Έ μμ§λ§ νμ μ΄ λ°μλμ΄μμ§ μμ κ²½μ°μλ μ¬μ©ν μ μμ κ² κ°λ€.
document.querySelector("#myButton")?.addEventListener("click", e => {
e.currentTarget
const button = e.currentTarget as HTMLButtonElement
button
})eventμ currentTargetμ λ°νμμμ κ²°μ λλ―λ‘ null|HTMLButtonElementμ€μμ HTMLButtonElementλ‘ μ ν΄μ€μΌ νλ€.
μ΅κ·Ό κ³Όμ λ₯Ό νλ©΄μ νμ
λ¨μΈμ΄ νμν κ²½μ°κ° μμλ€. μμ΄λ‘ μ€λμ μμΌμ κ°μ ΈμμΌ ν λ toLocaleDateString()λ₯Ό μ΄μ©ν΄μ μ¬μ©νλ € νμ§λ§ νμ
μ μκ° stringμΌλ‘ λμ΄μμ΄ νμ
μλ¬κ° λ°μνλ€.
μ΄μ μ ν΄κ²°νκΈ° μν΄μ κ³ λ―Όμ νλ€κ° μ μ λμ΄μλ νμ λ³΄λ€ λ μμΈν μ ν΄μ€μΌ νλ μν©μ΄λ―λ‘ νμ λ¨μΈμ μ¬μ©ν΄μ ν΄κ²°ν μ μμλ€.
const today = new Date()
const day = today.toLocaleDateString("en", {
weekday: "short",
}) as EnKeys
const Days = {
Mon: "μ",
Tue: "ν",
Wed: "μ",
Thu: "λͺ©",
Fri: "κΈ",
Sat: "ν ",
Sun: "μΌ",
Temp: "λΉμΌ",
} as const
export type EnKeys = keyof typeof Daysνμ
λ¨μΈμ νμ μ¬μ©ν μ μλ κ²μ μλλ€. A|B typeμμ Aκ° Bμ λΆλΆ μ§ν©μΌ λλ§ μ¬μ©ν μ μλ€.
interface Person {
name: string
}
const body = document.body
const el = body as Person
// Conversion of type 'HTMLElement' to type 'Person' may be a mistake because neither type sufficiently overlaps with the other. // If this was intentional, convert the expression to 'unknown' first.
const el = body as unkown as PersonPersonμΌλ‘ νμ
λ¨μΈμ ν΅ν΄ νμ
μ μ νλ € νμ§λ§ bodyκ° κ°μ§λ typeμΈ HTMLElementμ Personμ μλ‘ κ΄κ³κ° μκΈ° λλ¬Έμ μλ¬κ° λ°μνλ€. νμ§λ§ unknownμ κ°μ₯ ν° νμ
μ μ§ν©μ΄λ―λ‘ νμ
λ¨μΈμ΄ κ°λ₯ν κ²μ λ³Ό μ μλ€.
λ§μΉλ©°
νμ
μμ€ν
μ 곡λΆνλ©΄μ νμ
μ μ§ν©μ΄λΌλ μμ μΌλ‘ 보λ μ’ λ μ΄ν΄κ° μ λμλ€. νμ§λ§ μ¬μ ν λΆμ‘±ν μ μ΄ λ§μμ μ¬λ¬ λ² μ½μ΄μΌ ν λΆλΆμ΄λΌ μκ°λλ€.
[μ°Έμ‘°] μ΄νν°λΈ νμ μ€ν¬λ¦½νΈ