수 타입 -> number
불리언 타입 -> boolean
문자열 타입 -> string
객체 타입 -> object
let n : number = 1
let b : boolean = true
let s : string = 'hello'
let o : object = {}
타입이 다르게 입력되게되면 type 불일치 에러가 나타난다.
let n = 1 // number로 판단
let b = true // boolean으로 판단
let s = 'hello' // string으로 판단
자바스크립트와의 호환성을 위해 타입 주석 부분을 생략할수있다.
타입과 무관하게 어떤 종류의 값도 저장할수있다.
let a : any = 0
a = 'hello'
a = true
a = {}
javascript와는 다르게 typescript는 undefined를 type으로 여긴다
let u : undefinded = undefined
u = 1 // u는 type 불일치 에러
any는 모든 타입의 최상위타입이며, undefined type은 최하위 타입이다.
1] any ->
2] number, boolean, string
2] object -> interface, class
3] undefined
`${변수이름}`
문자열을 조합하여서 변수를 값으로 치환시킬수 있는 typescript의 방법
let o : object = {name: 'Jack', age: 32}
o = {first: 1, second: 2}
object 타입은 객체의 any 타입으로 동작하게된다.
이러한 것을 보안하기위해 interface를 사용한다
interface IPerson{
name : string
age : number
}
let good : IPerson = {name : 'Jack' , age: 32}
let bad1: IPerson = {name: 'Jack'} //age가 없으므로 error
let bad2: IPerson = {age: 32}//name이 없으므르 error
let bad3: IPerson = {} // name, age가 없으므로 error
let bad4: IPerson = {name: 'Jack', age: 32, etc: true}// etc가 있으므로 error
interface IPerson2{
name: string
age: number
etc?: boolean
}
let good1: IPerson2 = {name: 'Jack', age:32}
let good2: IPerson2 = {name: 'Jack', age:32, etc:true}
interface 중의 속성이 있어도되고 없어도 되게 만들고싶다면
선택속성(?)을 속성에다가 사용하여주면 편리하게 사용이 가능하다
선택속성은 변수명 뒤에 ?를 붙여주면된다.
let ai :{
name: string
age: number
etc?: boolean
} = {name: 'Jack', age: 32}
익명 인터페이스로 간단하게 코드를 구현할수있다.
ex를 보자면
function printMe(me : {name: string, age: number, etc?: boolean}){
console.log(me.etc ? `${me.name} ${me.age} ${me.etc}` : `${me.name} ${me.age}`)
}
printMe(ai)
typescript는 객체지향 언어에서 볼수있는 class, private, public, protected, implements, extend와 같은 키워드를 제공한다. 문법의 차이만 약간있고 의미는 같다.
class Person1{
name: string
age?: number
}
let jack1 : Person1 = new Person1()
jack1.name = 'Jack';
jack1.age = 32
console.log(jack1)
private, public, protected를 사용하며, 생략하면 public으로 간주한다.
여기에서 다른 언어와 다르게 나타나는 부분이있는데,
class Person2{
constructor(public name: string, public age?: number){}
}
let jack2 : Person2 = new Person2('Jack', 32)
console.log(jack2)
생성자의 매개변수에 public과 같은 접근제한자를 사용하면 매개변수의 이름을 가진 속성이 클래스에 선언된것처럼 동작하게된다. 즉 위의 코드가 아래의 코드와 같다고 볼수있다.
class Person3 {
name: string
age?: number
constructor(name: string, age?: number){
this.name = name;
this.age = age
}
}
let jack3 : Person3 = new Person3('Jack', 32)
console.log(jack3)
인터페이스의 중요한점은 인터페이스는 이러한 속성이 있어야한다는
규약이 정해져있을뿐 물리적으로 해당속성을 만들지는 않는다.
그래서 클래스에 인터페이스가 정의하고 있는 속성을 멤버 속성으로 포함시켜야한다.
interface IPerson4{
name: string
age?: number
}
class Person4 implements IPerson4{
name: string
age: number
}
console.log("Person4", Person4)
아래는 생성자와 public 키워드를 사용하여서 인터페이스를 구현한것
interface IPerson4 {
name: string
age?: number
}
class Person4 implements IPerson4{
constructor(public name: string, public age?: number){
this.name = name
this.age = age
}
}
let jack4: IPerson4 = new Person4('Jack', 32)
console.log(jack4)
typescript도 abstract 키워드를 사용하여서 추상 클래스를 만들수있다.
abstract class AbstractPerson5{
abstract name: string
constructor(public age?: number){}
}
// let jack5: AbstractPerson5 = new AbstractPerson5('Jack') //에러가난다
abstract가 붙었으므로 new 연산자를 사용하여서 객체를 만들수없다!
Person5 클래스는 AbstractPerson5 추상클래스를 상속하여 AbstractPerson5의
age를 얻고 AbstractPerson5를 상속받는 클래스가 만들어야할 name 속성을 구현한다.
타입스크립트에서는 부모클래스의 생성자를 super 키워드로 호출이 가능하다.
class Person5 extends AbstractPerson5{
constructor(public name:string, age?: number){
super(age) // 부모 생성자 호출
}
}
let jack6: Person5 = new Person5('Jack', 32)
console.log(jack5)
정적인 속성을 만드는 방법은 다른 언어와 마찬가지로 static을 사용하면 된다.
class A {
static initValue : number = 1
}
let initVal = A.initValue
A.initValue = 5
console.log(A.initValue)
let personName = 'Jack'
let personAge = 32
let companyName = 'Apple Company, Inc'
let companyAge = 43
//위의 코드를 사용하는것보단 아래처럼 구조화시키는게 효율적
//IPerson_ICompany.ts
export interface IPerson{
name: string
age: number
}
export interface ICompany{
name: string
age: number
}
import { IPerson, ICompany} from './IPerson_ICompany'
let jack : IPerson = {name: 'Jack', age: 32},
jane : IPerson = {name: 'jane', age: 32}
let apple : ICompany = {name: 'Apple Computer, Inc', age: 43},
ms : ICompany = {name: 'Microsoft', age: 44}
구조화된 데이터를 분해하는것을 비구조화라고한다.
import {IPerson} from './IPerson_ICompany'
let jack: IPerson = {name: 'Jack', age: 32}
let {name, age} = jack
console.log(name, age)
...연산자를 사용하는 용도에 따라 잔여, 전개연산자라 한다.
detail 변수에 남은 값들 입력하기
let address: any = {
country: 'Korea',
city: 'Seoul',
address1: 'Gangnam-gu',
address2: 'Sinsa-dong 123-456',
address3: '789 street, 2 Floor ABC building'
}
const {country, city, ...detail} = address
console.log(detail)
//address1: 'Gangnam-gu',
//address2: 'Sinsa-dong 123-456',
//address3: '789 street, 2 Floor ABC building'
객체 안에 있는 값들을 전부 펼쳐서 전개하는데에 사용하기
let part1 = {name: 'jane'}, part2 = {age: 22}, part3 = {city:'Seoul', country: 'Kr'};
let merged = {...part1, ...part2, ...part3}
console.log(merged)
자바스크립트와는 달리 타입스크립트는 아래는 에러가 된다.
person의 타입은 object인데 object는 name속성을 가지지 않으므로 에러가 발생
let person : object = {name: "Jack", age: 32};
person.name
{name: string} 타입으로 변환시켜서 person.name 속성을 얻게한다.
let person : object = {name: "Jack", age: 32};
(<{name: string}>person).name
타입변한대신 타입단언이라는 표현을 사용하며 아래의 두가지 형태를 가진다
(<타입>객체)
(객체 as 타입)
//INameable.ts
export default interface INameable{
name: string
}
import INameable from './INameable'
let obj: object = { name: 'Jack'}
let name1 = (<INameable>obj).name
let name2 = (obj as INameable).name
console.log(name1, name2)// Jack Jack