// 함수 타입 정의
type NumOut = (x: number, y: number) => number
// 함수에 타입 적용
let ABC: NumOut = function(x, y) {
return x + y
}
// 일반 함수
function add(x, y) {
return x + y
}
// Arrow Function
let add = (x, y) => {
return x + y
}
// 단축 문법
let multiply = (x, y) => x * y // return 생략
let double = x => x * 2 // 매개변수 1개일 때 괄호 생략
Arrow Function 특징:
this 값이 일반 함수와 다름// Type Alias 사용
type CalculatorType = (x: number, y: number) => number
let calculator: CalculatorType = (a, b) => a + b
// 직접 타입 지정
let calculator: (x: number, y: number) => number = (a, b) => a + b
주의: function 키워드에는 직접 타입 지정 불가
// 불가능
function 함수이름: NumOut() {}
// 가능
let 함수이름: NumOut = function() {}
let 회원정보 = {
name: 'kim',
age: 30,
plusOne(x) {
return x + 1
},
changeName: () => {
console.log('안녕')
}
}
// 메서드 호출
회원정보.plusOne(1)
회원정보.changeName()
type Member = {
name: string,
age: number,
plusOne: (x: number) => number,
changeName: () => void
}
let 회원정보: Member = {
name: 'kim',
age: 30,
plusOne(x) {
return x + 1
},
changeName: () => {
console.log('안녕')
}
}
function 함수1(callback) {
callback() // 매개변수로 받은 함수 실행
}
function 함수2() {
console.log('실행됨')
}
함수1(함수2) // '실행됨' 출력
// 문자열 앞의 0 제거
type CutType = (x: string) => string
let cutZero: CutType = function(x) {
let result = x.replace(/^0+/, "")
return result
}
// 대시 제거 후 숫자로 변환
type RemoveType = (x: string) => number
let removeDash: RemoveType = function(x) {
let result = x.replace(/-/g, "")
return parseFloat(result)
}
type CutType = (x: string) => string
type RemoveType = (x: string) => number
function 처리함수(
text: string,
func1: CutType,
func2: RemoveType
) {
let result1 = func1(text) // 첫 번째 함수 실행
let result2 = func2(result1) // 두 번째 함수 실행
console.log(result2)
}
// 사용 예시
처리함수('010-1111-2222', cutZero, removeDash) // 1011112222 출력
// tsconfig.json
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"strictNullChecks": true // 또는 "strict": true
}
}
<!-- index.html -->
<h4 id="title">안녕하세요</h4>
<a id="link" href="naver.com">링크</a>
<button id="button">버튼</button>
<img id="image" src="test.jpg">
<script src="app.js"></script>
let 제목 = document.querySelector('#title')
제목.innerHTML = '반갑소' // 에러! 제목이 null일 수 있음
문제 원인: querySelector는 Element | null 타입 반환
let 제목 = document.querySelector('#title')
if (제목 != null) {
제목.innerHTML = '반갑소'
}
let 제목 = document.querySelector('#title')
if (제목 instanceof HTMLElement) {
제목.innerHTML = '반갑소'
}
let 제목 = document.querySelector('#title') as HTMLElement
제목.innerHTML = '반갑소'
let 제목 = document.querySelector('#title')
if (제목?.innerHTML != undefined) {
제목.innerHTML = '반갑소'
}
Element
├── HTMLElement
├── HTMLAnchorElement (a 태그)
├── HTMLImageElement (img 태그)
├── HTMLButtonElement (button 태그)
├── HTMLInputElement (input 태그)
├── HTMLHeadingElement (h1~h6 태그)
└── ...
// a 태그의 href 속성 수정
let 링크 = document.querySelector('#link')
if (링크 instanceof HTMLAnchorElement) {
링크.href = 'https://kakao.com' // 정상 작동
}
// img 태그의 src 속성 수정
let 이미지 = document.querySelector('#image')
if (이미지 instanceof HTMLImageElement) {
이미지.src = 'new.jpg'
}
// button 태그 이벤트 리스너
let 버튼 = document.querySelector('#button')
if (버튼 instanceof HTMLButtonElement) {
버튼.addEventListener('click', function() {
console.log('클릭됨')
})
}
let 링크 = document.querySelector('#link')
if (링크 instanceof HTMLElement) {
링크.href = 'https://kakao.com' // 에러! HTMLElement에는 href 속성 없음
}
let 링크들 = document.querySelectorAll('.naver')
링크들.forEach((링크) => {
if (링크 instanceof HTMLAnchorElement) {
링크.href = 'https://kakao.com'
}
})
let 링크들 = document.querySelectorAll('.naver')
for (let i = 0; i < 링크들.length; i++) {
let 링크 = 링크들[i]
if (링크 instanceof HTMLAnchorElement) {
링크.href = 'https://kakao.com'
}
}
타입: querySelectorAll은 NodeListOf<Element> 반환
let 버튼 = document.getElementById('button')
if (버튼 instanceof HTMLButtonElement) {
버튼.addEventListener('click', function() {
console.log('안녕')
})
}
let 버튼 = document.getElementById('button')
버튼?.addEventListener('click', function() {
console.log('안녕')
})
Optional Chaining 동작:
버튼이 존재하면 addEventListener 실행버튼이 null이면 undefined 반환 (에러 없음)let 버튼 = document.querySelector('#changeBtn')
let 이미지 = document.querySelector('#image')
if (버튼 instanceof HTMLButtonElement && 이미지 instanceof HTMLImageElement) {
버튼.addEventListener('click', function() {
이미지.src = 'new.jpg'
})
}
let 폼 = document.querySelector('#myForm')
let 입력창 = document.querySelector('#nameInput')
if (폼 instanceof HTMLFormElement && 입력창 instanceof HTMLInputElement) {
폼.addEventListener('submit', function(e) {
e.preventDefault()
console.log('입력값:', 입력창.value)
})
}
let 제목들 = document.querySelectorAll('h4')
제목들.forEach(제목 => {
if (제목 instanceof HTMLHeadingElement) {
제목.style.color = 'red'
제목.style.fontSize = '20px'
}
})
// 앞의 0 제거
let text = "00123"
let result = text.replace(/^0+/, "") // "123"
// 모든 대시 제거
let phone = "010-1234-5678"
let cleaned = phone.replace(/-/g, "") // "01012345678"
// 숫자만 추출
let mixed = "abc123def456"
let numbers = mixed.replace(/[^0-9]/g, "") // "123456"
/^0+/: 문자열 시작에서 0이 1개 이상/-/g: 모든 대시 문자 (g는 global, 전체)/[^0-9]/g: 숫자가 아닌 모든 문자function isHTMLElement(element: Element | null): element is HTMLElement {
return element instanceof HTMLElement
}
function isHTMLAnchorElement(element: Element | null): element is HTMLAnchorElement {
return element instanceof HTMLAnchorElement
}
// 사용
let 링크 = document.querySelector('#link')
if (isHTMLAnchorElement(링크)) {
링크.href = 'https://example.com'
}
function safeQuerySelector<T extends HTMLElement>(
selector: string,
type: new () => T
): T | null {
let element = document.querySelector(selector)
if (element instanceof type) {
return element
}
return null
}
// 사용
let 버튼 = safeQuerySelector('#button', HTMLButtonElement)
if (버튼) {
버튼.addEventListener('click', () => console.log('클릭'))
}
function 안전한DOM조작() {
try {
let 요소 = document.querySelector('#target')
if (요소 instanceof HTMLElement) {
요소.innerHTML = '새 내용'
} else {
console.warn('요소를 찾을 수 없습니다')
}
} catch (error) {
console.error('DOM 조작 중 오류:', error)
}
}
// 일반적인 조작만 할 경우
if (element instanceof HTMLElement) { }
// 특정 속성 접근이 필요한 경우
if (element instanceof HTMLAnchorElement) { } // href 접근
if (element instanceof HTMLImageElement) { } // src 접근
if (element instanceof HTMLInputElement) { } // value 접근
getElementById는 더 빠르고 HTMLElement 반환querySelector는 유연하지만 Element | null 반환let 요소 = document.querySelector('#test')
console.log(요소) // null인지 확인
console.log(요소 instanceof HTMLElement) // 타입 확인