type bts = {
debut: number;
name: string;
};
interface bts {
debut: number;
name: string;
}
=> 위의 두 구분은 거의 같다.
tip) 세미콜론(;)을 선호하는 타입스클비트 개발자는 대부분 인터페이스 뒤가 아닌 타입별창 뒤에 세미콜론을 넣는다. 이 기본 설정은 세미콜론을 사용해 변수를 선언하는 것과 세미콜론 없이 클래스 또는 함수를 선언하는 것의 차이를 반영한다.
let valueHybe: Bts;
// ok
valueHybe = {
dubut: 2013;
name: "bangTan",
};
valueHybe = "V";
// Error: Type 'string' is not assignable to 'Bts'.
valueHybe = {
debut: true,
// Error: Type 'boolea' is not assignabel to type 'number'.
name: 'Jimin'
};
interface Pachinko {
author?: string;
pages: number;
};
// ok
const ok: Pachinko = {
author: "min Jin Lee",
pages: 527,
};
const missing: Pachinko = {
pages: 527
};
-> Book 인터페이스는 필수 속성 pages의 선택적 속성 author 를 갖는다
-> Book 인터페이스를 사용하는 객체에 필수 속성만 제공된다면 선택적 속성은 제공되거나 생략할 수있다.
interface Page {
readonly text: string;
}
function read(page: Page) {
// ok: text 속성을 수정하지 않고 읽는 것
console.log(page.text);
page.text += "!";
// Error : Cannot assign to 'text' because it is a read-only property.
}
const pageIsh = {
text: "Hi, There!",
};
// ok : pageIsh는 page 객체가 아니라 text가 있는, 유추뒨 겍체 타입이다.
pageIsh.text += "!";
// ok : pageIsh의 더 구체적인 버전인 Page를 읽는다
read(pageIsh);
interface HasBothFunctionTypes {
property: () => string;
method(): string;
}
const hasBoth: HasBothFunctionTypes = {
property: () => "",
method() {
return "";
}
};
hasBoth.property(); // ok
hasBoth.method(); // ok
=> 두 가지 방법 모두 선택적 속성 키워드인 ?를 사용해 필수로 제공하지 않아도 되는 멤버로 나타낸다.
interface OptionalReadonlyFunctions {
optionalProperty?: () => string;
oprtionalMethod?() : string;
}
type Func = (input: string) => number;
interface CallSignature {
(input : string): number;
}
// 타입 : (input : string) => number
const typedFunc: Func = (input) => input.length; //ok
// 타입 : (input: string) => number
const typeCallSignature: CallSignature = (input) => input.length; // ok
interface FuncWithCount{
count: number;
(): void;
}
let hasCallCount: FuncWithCount;
function keepsTrackOfCalls() {
keepTrackOfCalls.count += 1;
console.log("Hi There! ${keepsTrackOfCalls.count} times!');
}
keepsTrackOfCalls.count = 0;
hasCallCount = keepsTrackOfCalls; // ok
function doesNotHaveCount() {
console.log("No idea!");
}
hasCallCount = doesNotHaveCount;
// Error : Property 'count' is missing in type
// '() => void' but required in type 'FuncWithCount'
=> keepsTrackCalls 함수 선언에서는 number 타입인 counter 속성이 주어져 funcWithCount 인터페이스 할당 할 수 있다.
=> FuncWithCount 타입의 hasCallCount 인수에 할당 할 수 있다.
interface BtsNums {
[i: string]: number;
}
const nums: BtsNums = {};
nums.v = 0; // ok
nums.jimin = 1; // ok
nums.rm = false;
// Error : Type 'boolean' is not assignable to type 'number'.
BtsNums 인터페이스는 number 값을 갖는 모든 string 키를 허용하는 것으로 선언된다.
number면 string 키가 아닌 그 어떤 키도 바인딩 할 수 없다.
- 인덱스 시그니처는 객체에 값을 할당 할 때 편리하지만 타입 안전성을 완벽학게 보장하진느 않는다.
- 인댁스 시그니처는 객체가 어떤 속성에 접근하든 간에 값을 반환해야 한다.
interface DatesByBts {
[i: string]: Date;
}
const publishDate: DateByBts = {
Frankenstein: new Date("1 January 1818"),
};
publishDates.Frankenstein; // 타입: Date
console.log(publishDates.Frankstein.toString()); // ok
publishDates.Beloved; // 타입은 Date 이지만 런타임 값은 undefined
console.log(publishDates.Beloved.toString());
// 타입 시스템에서는 오류가 나지 않지만 실제 런타임에서는 오류가 발생함
// Runtime error: Cannot read property 'toString'
// of undefined (reading publishDates.Beloved)
=> publishDats 값은 Date 타입으로 Frankenstein을 안전하게 반환하지만 타입스크립는 Beloved 가 정의되지 않았음에도 불구하고 정의되었다고 생각한다.
interface FlyHight {
Oroonoko: number;
[i: stirng]: number;
}
// ok
const fly: FlyHight = {
Outlander: 1991,
Oroonoko: 1688,
};
const missingOroonoko: FlyHight = {
// Error: Property 'Oroonoko' is missing in type
// '{ Outlander: number; }' but required in type 'FlyHight'.
Outlander: 1991,
};
interface HybeNewJeans {
members: 5;
[i, string]: number;
}
const corretMembers: HybeNewJeans = {
members: 5;
night: 1;
shopping: 7
};
const wrongMembers: HybeNewJeans = {
members: 1,
Error: Type '1' is not assignable to type '5'.
};
// ok
interface MoreNarrowNumbers {
[i: number]: string;
[i: string]: string | undefined
}
// ok
const mixesNumbersAndStrings: MoreNarrowNumbers = {
0: '';
key1: '',
key2: undefined,
}
interface MoreNarrowStrings {
[i: number]: string | undefined;
// Error: 'number' index type string | undefined'
// is not assignable to 'string' index type 'string'
[i: string]: string;
}
-MoreNarrowNumbers 인터페이스는 string을 string | undefined 에 할당할 수 있지만 MoreNarrowStrings 인터페이스는 string | undefined 을 string 할당 할 수 없다.
interface Novel {
author: {
name: string;
};
setting: Setting;
}
interface Setting {
place: string;
year: number;
}
let myNovel: Novel;
// ok
myNovel = {
author: {
name: 'Min Jin Lee',
},
setting: {
place: 'NY',
year: 2018,
}
};
myNovel = {
author: {
name: 'Emily Bronte',
},
setting: {
// Error: Property 'year' is missing in type
// { place: string } but required in type 'Setting'
place: 'West',
},
};
확장된
인터페이스를 허용한다.interface Writing {
title: string;
}
interface Novella extends Writing {
pages: number;
}
// ok
let myNovella: Novella = {
pages: 222,
title: 'Ethan',
};
let missingPages: Novella = {
// Error: Property 'pages' is missing in type '{ title: string }' but
// required in type 'Novella'
title: "Wake up".
};
let extraProperty: Novella = {
// Error: Type '{ pages: number; strategy: string; style: string; }'
// is not assignable to type 'Novella'.
// Object literal may only specify known properties,
// and 'strategy' does not exist in type 'Novella'
pages: 300,
strategy: 'baseline',
style: 'Naturalis'
};
interface WithNullableName {
name: string | null;
}
interface WithNonNullableName extends WithNullableName {
name: string;
}
interface WithNumricName extends WithNullableName {
// Error : Interface 'WithNumericName' incorrectly extends interface
// 'WithNullableName'.
// Type of property 'name' are incompatible.
// Type 'string | number' is not assignable to type 'string | ull'.
// Type 'number' is not assignable to type 'string'
name: number | string;
}
interface GivesNumber {
giveNumber(): number;
}
interface GivesString {
giveString(): string;
}
interface GivesBothEither extens GivesNumber, GivesString {
giveEither(); number | string;
}
function useGivesBoth(instance: GivesBothEither) {
instance.giveEither(); // 타입: number | string
instance.giveNumber(); // 타입: number
instance.giveString(); // 타입: string
}
interface Merged {
fromFirst: string;
}
interface Merged {
fromSecond: number;
}
// interface Merged {
// fromFirst : string
// fromSecond : number;
// }
interfase Window {
myEnviVariable: string;
}
window.myEnvibariable; // 타입 : string
interface MergedProperties {
same: (input:boolean) => string;
different: (input: string) => string;
}
interface MergedPropertyies {
same: (input: boolean) => string // ok
different: (input: number) => string;
// Error: Subsequent property declarations must have the same type.
// Property 'differnt' must be of type '(input: string)' => string.
// but here has type '(input: string) => string'.
interface MergedMethods {
diffrent(input: string): string;
}
interface MergedMethods {
different (input: number): string; //ok
}