typescript Interface
01. Wath art Interfaces
어떤 type을 만들어 내는 방식
예전에는 내부적으로 숨겨져있고, 외부적으로 드러나는 호출 방식
내부적인것과 관계없이 외부적으로 들어나는 객체의 사용방식
//interface가 없으면
function hello2(person:{name:string, age:number}): void{
console.log(`hi my name ${person.name}, age is ${person.age} `);
}
//interface 사용하면...
interface Person1 {
name:string,
age:number
}
function hello1(person:Person1): void{
console.log(`hi my name ${person.name}, age is ${person.age} `);
}
const p1:Person1 = {
name:"Mark",
age:39
}
hello1(p1)
//사실 {name:string, age:number} 로만 호출도 가능하다. 구조가 같아서 호출 가능
//근데 이 부분을 interface으로 만들면 더 깔끔하다.
hello1({name:"Qwe", age:45})
타입스크립트에서는 interface가 중요하다.
javascript에서는 없는 문법이며, 컴파일 했을 때 javascript에는 나오지 않는다.
컴파일 타임에만 필요하다. 컴파일 타임에 문제가 없는지 관계를 규명한다.
컴파일 결과 (javascript)
"use strict";
function hello1(person) {
console.log(`hi my name ${person.name}, age is ${person.age} `);
}
const p1 = {
name: "Mark",
age: 39
};
hello1(p1);
hello1({ name: "Qwe", age: 45 });
02. Optional Property(1)
항상 필요한 property가 아니고, 필요에 따라서 있을 수도 있고, 없을 수도 있는 property
interface Person2 {
name:string;
age?:number; //?달아 optional을 표현
}
function hello(person:Person2):void {
console.log(`hello person2 name ${person.name}입니다.`)
}
hello ({name:"hong", age:123})
hello({name:"qwe"}) //Person2에 age를 않넣어줘도 오류가 안난다. optional이기 때문에
const a1:Person2 = {
name:"hh"
}
hello(a1)
03. Optional Property(2)
interface에 optional type을 넣는 다른 방법
indexable type ...
문법은
[index:string]:type
a['index] 와 같은 의미...어떤것을 프로퍼티 이름으로 지정할 수 있고,
근데 사용하는 쪽에서는 호출하는 쪽 구조를 알아야되서 잘 안쓸수도 있겠다는 생각이 든다....
interface Person3 {
name:string;
age?:number;
[index:string]:any; //어떤 이름의 프로퍼티가 와도 괜찮아....indexable type
}
function hello3(person:Person3):void {
console.log(`Hello ${person.name}`)
console.log(person.father)
console.log(person['father'])
console.log(person.mother)
}
const p31:Person3 = {
name:'Mark',
age:39,
};
const p32:Person3 = {
name:"hong",
systers:['A', 'B', 'C'] //[index:string]:any에 대응되는 부분
}
const p33:Person3 = {
name:"Bob",
father : p31,
mother:p32
};
hello3(p33)
04. function in interface
interface 안에 함수를 정의하는 방법
hello()을 객체를 정의하는 곳에서 같이 만들어야한다. p41, p42 참고
array function에서는 this를 사용할 수 없다.
interface Person4 {
name:string;
age:number;
hello():void //hello를 객체에서 만들어내야한다.
}
const p41:Person4 = {
name:'Mark',
age:39,
//만드는 방법 1
//hello의 타입을 function으로 지정
hello:function():void {
console.log(`hello ${this.name}`)
}
}
const p42:Person4 = {
name:'Mark',
age:39,
//만드는 방법 2
//hello를 ()로 사용하는 방법
hello():void {
console.log(`hello ${this.name}`)
}
}
// const p43:Person4 = {
// name:'Mark',
// age:39,
// //만드는 방법 3, arrow function
// //화살표함수는 this를 사용할 수 없다..에러에러에러!!
// //global this를 가르킨다
// hello:():void => {
// console.log(`hello ${this.name}`)
// }
// }
p41.hello()
p42.hello()
05. class implements interface
interface를 사용해서 클래스를 구현하는 방법...
java에서 많이 썼던것 같음...
interface는 컴파일 타임에서만 사용
클래스는 javascript의 feature로 들어가 있음
interface에 있는 내용을 바탕으로 클래스를 만들어 내는 것
interface IPerson1 {
name:string;
age?:number;
hello():void;
};
class Person implements IPerson1 {
name: string;
age?: number | undefined; //없어도 큰 문제가 없다.
hello(): void {
//throw new Error("Method not implemented.");
console.log(`Class Person hello ${this.name}`)
}
constructor(name:string) {
this.name = name
}
}
//클래스 또한 타입처럼 사용가능
//Person이 IPerson1을 구현했기 때문에 아래와 같이 사용해도 된다.
//const person:IPerson1 = new Person('Hong');
const person = new Person('Hong');
person.hello()
oop에서 interface만 노출하고 구현은 노출하지 않는 방법..
06. interface extends interface
interface 끼리 상속하는 방법...
interface IPerson2 {
name:string;
age?:number
}
interface IKorea extends IPerson2 {
city:string;
}
//IKorea는 IPerson2를 확장하는것
const k:IKorea = {
name:"Hong",
city:"seoul"
};
console.log(k.name, k.city)
07. function interface
함수를 곧 interface로..
age는 optional이니까 있어도, 없어도 상관없고
대신 구현하는 곳...즉 function(name:string, age:number)로 쓰면 에러가 난다.
이유는 interface와 function이 맞지 않다...
interface쪽에는 number | undefined이고 function에 있는건 number이기때문에
더 큰 타입을 작은 타입에 넣지 못하기 때문이다...
//helloperson을 사용하는 객체는 (name:string, age?:number):void 형태로 작성되어야한다.
interface HelloPerson {
(name:string, age?:number):void
}
//helloPerson은 뒤에 따라오는 function이하를 보는게 아니라 HelloPerson interface를 본다.
//interface와 type이 맞아야 한다...
//그래서 function(name:string, age:number)는 에러이다.
//interface의 age는 number | undefinded 타입이고,
//function의 age는 number다...
const helloPerson:HelloPerson = function(name:string) {
console.log(`helloPerson ${name}`)
}
helloPerson('Mark', 40)
08. Readonly interface properties
interface Person8 {
name:string;
age?:number;
readonly gender:string;
}
const p81:Person8 = {
name:'Mark',
gender:'male'
};
//error
//readonly 타입에 변경하므로...
//p81.gender = 'female'
09. type alias vs interface
추가적으로 읽어볼 블로그
https://poiemaweb.com/typescript-alias
TypeScript - Type Alias | PoiemaWeb
poiemaweb.com
https://joonsungum.github.io/post/2019-02-25-typescript-interface-and-type-alias/
TypeScript에서 Type을 기술하는 두 가지 방법, Interface와 Type Alias
타입스크립트를 사용하기 시작한 뒤로 type을 기술할 때, 일반적인 상황에서는 특별한 고민 없이 interface를 사용하고 있었다. TypeScript 공식 문서에서 특별한 상황이 아니라면 interface의 사용을 권
joonsungum.github.io
https://poiemaweb.com/typescript-interface
TypeScript - Interface | PoiemaWeb
인터페이스는 일반적으로 타입 체크를 위해 사용되며 변수, 함수, 클래스에 사용할 수 있다. 인터페이스는 여러가지 타입을 갖는 프로퍼티로 이루어진 새로운 타입을 정의하는 것과 유사하다.
poiemaweb.com
//function을 표현하는 방법
//type alias
type EatType = (food:string) => void;
//interface
interface IEat {
(food:string):void;
}
//array를 표현하는 방법
//type alias
type PersonList = string[];
//interface
interface IPeronList {
[index:number]:string; //indexable type
}
//intersection
interface ErrorHandling {
success:boolean;
error?:{message:string};
}
interface ArtistsData {
artists:{name:string}[]
}
//type alias
type ArtistsResponseType = ArtistsData & ErrorHandling
//interface
interface IArtistsResponse extends ArtistsData, ErrorHandling{}
let art:ArtistsResponseType;
let iar:IArtistsResponse;
//union type
interface Birt {
fly():void;
layEggs():void;
}
interface Fish {
swit():void;
layEggs():void;
}
// type은 union 가능...
type PetType = Birt | Fish;
//union type은 extends나 implements 불가
//어느 타입인지 혼동된다...타입이 두개잖아...
// interface IPet extends PetType {}
// class Pet implements PetType {}
//Declaration Mergin - interface
interface MerginInterface {
a:string
}
interface MerginInterface {
b:string
}
//두개의 interface가 이름이 같으므로 하나로 합쳐진다..
let mi:MerginInterface;
//type alias 는 merging가 불가
//같은 이름이면 에러 남
// type MergingType = {
// a:string;
// }
// type MergingType = {
// b:string;
// }