// 해시맵 만들기
type Words = {
[key: string]: string;
};
class Dict {
private words: Words;
constructor() {
this.words = {};
}
add(word: Word) {
if (this.words[word.term] === undefined) {
this.words[word.term] = word.def;
}
}
get(term: string) {
return this.words[term];
}
delete(term: string) {
if (!this.words[term]) return false;
delete this.words[term];
return true;
}
update(term: string, def: string) {
if (!this.words[term]) return false;
this.words[term] = def;
return this.words[term];
}
showAll() {
return this.words;
}
count() {
return Object.keys(this.words).length;
}
}
class Word {
constructor(public readonly term: string, public readonly def: string) {}
}
const kimchi = new Word("kimchi", "한국의 음식")
const dict = new Dict()
dict.add(kimchi)
console.log(dict.get("kimchi"))
// dict.delete("kimchi")
// console.log(dict.get("kimchi"))
// dict.update("kimchi", "수정")
// console.log(dict.get("kimchi"))
// console.log(dict.get("kimchi"))
// const apple = new Word("apple", "과일")
// dict.add(apple)
// console.log(dict.showAll())
// const apple = new Word("apple", "과일")
// dict.add(apple)
// const banana = new Word("banana", "과일")
// dict.add(banana)
// console.log(dict.count())
// Type과 interface
type Team = "read" | "blue" | "yellow";
type Health = 1 | 5 | 10; // 인터페이스는 이런건 불가능하다.
// type Player = {
// nickname: string;
// team: Team;
// health: Health;
// };
interface Player { // 위 아래 둘다 똑같이 작동한다.
nickname: string;
team: Team;
health: Health;
}
// 인터페이스는 오로지 오브젝트의 모양을
// 타입스크립트에게 설명해주기 위해서만 사용되는 키워드다.
const nico: Player = {
nickname: "nico",
team: "yellow",
health: 10,
};
// interface로 상속구현
interface User1 {
name: string
}
interface Player1 extends User1 {
}
const jyj : Player1 = {
name:"jyj"
}
// 타입으로 상속구현
type User2 = {
name: string
}
type Player2 = User2 & {
}
const jyj2 : Player2 = {
name:"jyj"
}
클래스나 오브젝트의 모양을 정의할 때는 인터페이스를 사용하고 나머지는 type을 사용한다.(type alias나 특정 값으로 타입을 제한하는 경우 등)
// 추상클래스는 표준화된 property와 메소드를 갖도록 해주는
// 청사진을 만들기 위해 사용한다.
abstract class User {
constructor(protected firstName: string, protected lastName: string) {}
abstract sayHi(name:string):string
abstract fullName():string
}
class Player extends User {
fullName() {
return `${this.firstName} ${this.lastName}`;
}
sayHi(name: string) {
return `Hello ${name}. My name is ${this.fullName}`;
}
}
// 위와 같은 추상클래스는 인터페이스로 바꿀 수 있다.
interface User {
firstName: string;
lastName: string;
sayHi(name: string): string;
fullName(): string;
}
interface Human {
health: number;
}
class Player implements User, Human {
// 다중 상속 가능
// interface를 상속받으면 private이나 protect를 사용할 수 없다.
constructor(
public firstName: string,
public lastName: string,
public health: number
) {}
fullName() {
return `${this.firstName} ${this.lastName}`;
}
sayHi(name: string) {
return `Hello ${name}. My name is ${this.fullName}`;
}
}
// 인터페이스를 타입으로 받기, 리턴하기
// User인터페이스를 타입으로 받고 User인터페이스를 리턴
function makeUser(user: User) : User {
return {
firstName: "hi",
lastName: "bye",
sayHi: (name) => "hi",
fullName: () => "wow",
}; // 클래스를 리턴할 때 처럼 new User()같은 것을 할 필요가 없다.
}
makeUser({
firstName: "hi",
lastName: "bye",
sayHi: (name) => "hi",
fullName: () => "wow",
});
// LocalStorage API
interface SStorage<T> {
[key: string]: T;
}
abstract class StorageTemplate<T> {
protected storage: SStorage<T> = {};
abstract setItem(key: string, value: T): void;
abstract getItem(key: string): T | boolean;
abstract clearItem(key: string): void;
abstract clear(): void;
}
class LocalStorage<T> extends StorageTemplate<T> {
setItem(key: string, value: T) {
this.storage[key] = value;
}
getItem(key: string): T | boolean {
return this.storage[key] || false;
}
clearItem(key: string) {
delete this.storage[key];
}
clear() {
this.storage = {};
}
}
// polymorphism
const stringStorage = new LocalStorage<string>();
stringStorage.setItem("안녕", "반가워");
stringStorage.getItem("안녕");
const booleanStorage = new LocalStorage<boolean>();
booleanStorage.setItem("안녕", true);
booleanStorage.getItem("안녕");
interface IGeolocation {
clearWatch(watchId: number): void;
getCurrentPosition(
successCallback: IPositionCallback,
errorCallback?: IPositionErrorCallback | null,
options?: IGeolocationOptions
): void;
watchPosition(
successCallback: PositionCallback,
errorCallback?: IPositionErrorCallback | null,
options?: IGeolocationOptions
): number;
}
// successCallback interface
interface IPositionCallback {
(position: IGeolocationPosition): void;
}
interface IGeolocationPosition {
readonly coords: IGeolocationCoordinates;
readonly timestamp: IEpochTimeStamp;
}
interface IGeolocationCoordinates {
readonly accuracy: number;
readonly altitude: number | null;
readonly altitudeAccuracy: number | null;
readonly heading: number | null;
readonly latitude: number;
readonly longitude: number;
readonly speed: number | null;
}
type IEpochTimeStamp = number;
// errorCallback interface
interface IPositionErrorCallback {
(positionError: IGeolocationPositionError): void;
}
interface IGeolocationPositionError {
readonly code: number;
readonly message: string;
readonly PERMISSION_DENIED: number;
readonly POSITION_UNAVAILABLE: number;
readonly TIMEOUT: number;
}
// option interface
interface IGeolocationOptions {
enableHighAccuracy: boolean;
timeout: number;
maximumAge: number;
}
// Geolocation class
class GGeolocation implements IGeolocation {
clearWatch(watchId: number) {
console.log(watchId);
}
getCurrentPosition(
successCallback: IPositionCallback,
errorCallback?: PositionErrorCallback | null,
options?: PositionOptions
) {
if (successCallback) console.log(successCallback);
if (errorCallback) console.log(errorCallback);
if (options) console.log(options);
}
watchPosition(
successCallback: PositionCallback,
errorCallback?: PositionErrorCallback | null,
options?: PositionOptions
) {
if (successCallback) console.log(successCallback);
if (errorCallback) console.log(errorCallback);
if (options) console.log(options);
return 0;
}
}
const geolocation = new GGeolocation();
// 오버로딩
geolocation.getCurrentPosition(test);
geolocation.getCurrentPosition(test, test);
geolocation.getCurrentPosition(test, test, {});
function test() {}