abstract키워드는 사용하지 않음. interface SquareConfig{
  color?: string
  width?: number
}interface Point{
	readonly x: number
    readonly y: number
}
let point: Point = { x: 10, y:20 };
point.x =5 // Cannot assign to 'x' because it is a read-only property interface SearchFunc{
	(source : string, subString: string): boolean 
}interface Animal{
	makeSound(): void
}interface Animal {
	makeSound(): boid
}
interface Dog extends Animal {
	speed : number
}interface Counter {
	(start: number):string
    interval: number
    reset(): void
}
function getCounter(): Counter {
	let counter = function (start: number){} as counter
    counter.interval = 123;
    counter.reset = function(){}
    return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
interface를 활용한 디자인 패턴(Strategy pattern) : 객체가 할 수 잇는 행위들을 전략으로 만들어두고 동적으로 행위의 수정이 필요한 경우 전략을 바꾸는 것 만으로 수정이 가능하도록 만든 패턴
메소드 방식의 문제점 : OCP(Open Closed Principle) 위배, 시스템이 커져서 확장될 경우 연동되는 시스템에도 영향을 줄 수 있음.
interface PaymentStrategy {
	pay(): void	
}
class CardPaymentStrategy implements PaymentStrategy{
  pay(): void{
  	console.log("card pay!")
  }
}
class CashPaymentStrategy implements PaymentStrategy{
	pay(): void{
   	  console.log("Cash pay!");
    } 
}
class VendingMachine{
  private paymentStrategy: PaymentStrategy
  
  setPaymentStrategy(paymentStrategy: PaymentStrategy){
    this.paymentStrategy = paymentStrategy;}
}
	pay(){
	this.paymentStrategy.pay();
	}
}const vendingMachine = new VendingMachine();
vendingMachine.setPaymentStrategy(new CashPaymentStrategy());
vendingMachine.pay(); //cash pay
vendingMachine.setPaymentStrategy(new CardPaymentStrategy());
vendingMachine.pay(); //card pay//제네릭으로 함수 만들기
function sort<T>(items: T[]): T[]{
	return items.sort();
}
const nums: number[] = [1,2,3,4];
const chars: string[] = ["a","b","c","d"]
sort<number>(nums);
sort<string>(chars);//제네릭으로 클래스 만들기
class Queue<T>{
	protected data: Array<T> = [];
    push(item:T){
      this.data.push(iem);
      }
    pop(): T | undefined{
      return this.data.shift();
    }  
}
  const printMessage = <T extends string|number>(message: T): T => {
	return message;
}
printMessage<String>("1");
printMessage<Number>(1);
printMessage<Boolean>(false); //Error
const getProperty = <T extends object, U extends keyof T> (obj: T, key: U) => {
	return obj[key];
}
getProperty({a:1 , b:2 , C:3}, "a");
getProperty({a:1, b:2, c:3}, "z"); //error