타입스크립트는 object같은 단순한 이름이 아니라 객체의 구조를 기준으로 타입을 정의한다. 이러한 특징을 구조적 type 시스템이라 한다. (property based type system = 프로퍼티 기반 타입시스템)
(C와 같이 이름을 기준으로 타입을 지정하는것은 명목적 타입시스템이라 한다.)
let user: object = {
id: 1,
name:'heesu'
}
// user가 객체라는 것만 지정해주고 다른 정보가 없기때문에 에러가 난다.
user.id ;
let uesr1: {
**id?**: number;
name: string
} = {
id: 1,
name: '히수'
}
// 객체 리터럴 타입으로 id 프로퍼티에 접근하면 오류없이 잘 수행된다.
user1.id;
// user1안에 id는 ?를 붙혀서 있어도 되고, 없어도 되는 프로퍼티이기 때문에 오류가 나지 않는다.
user1 = {
name:'홍길동'
}
바꾸면 안되는 값에는 readonly
let config: {
readonly apiKey: string;
] = {
apiKey: 'API KEY'
}
// 읽기전용 속성으로 변경할 수 없다는 에러가 뜬다.
config.apikey = 'hackged'
타입을 객체마다 지정하지 않고, 마치 변수처럼 사용할 수 있다.
type dogType = {
name?: string;
color: string;
}
let dog: dogType = {
name : '멍멍이',
color: 'brown'
}
let dog2: dogType = {
name:'왈왈이',
color:'white'
}
type dogType = {
name?: string;
color: string;
}
// 타입 별칭은 변수와 똑같이 같은 스코프내에서 중복된 이름으로 선언하면 오류가 난다.
~~type dogType = {
}~~
// 여긴가능!
~~~~function func(){
type dogType = {};
}
type CountryCodes = {
// 문자열 key에 대해 string value를 가지는 모든 프로퍼티를 허용
// Key:string의 이유??
// 원래는 "Korea" | "unitedState" 와 같이 유니온 타입으로 key를 제한할 수 있으나,
// 인덱스 시그니처([key: string])를 사용해 의도적으로 key 제약을 제거함
[key: string]: string;
}
let countryCodes: CountryCodes = {
Korea: "ko",
unitedState: 'us',
UnitedKingdom:'uk'
}
type CountryNumberCodes= {
[key: string]: number
}
let countryNumberCodes:CountryNumberCodes = {
Korea: 410,
unitedState: 840,
UnitedKingdom: 826
}
인덱스 시그니처 타입은 지정한 타입을 위반하지 않으면 에러가 나지 않는다. 그래서 아래 코드의 CountryNemberCoeds2가 아무런 에러가 나지않는 것 (위반할 프로퍼티가 없음)
type CountryNumberCodes2= {
[key: string]: number;
}
let countryNumberCodes2:CountryNumberCodes2 = {}