July 12, 2021
type TState = {
name: string
capital: string
}
interface IState {
name: string
capital: string
}
named 타입은 타입으로 정하던, interface로 정하던 상태에는 차이가 없다.
const wyoming: TState = {
name: 'Wyoming',
capital: 'Cheyenne',
population: 500000, // error !
}
Object Literal 형식에는 정의한 속성만 지정할 수 있으며 TState에 population이 없기 때문에 에러가 난다.
type TDict = { [key: string]: string }
interface IDict {
[key: string]: string
}
index signiture는 interface와 type 모두에서 사용할 수 있다.
type TFn = (x: number) => string
interface IFn {
(x: number): string
}
const toStrT: TFn = x => '' + x // 정상
const toStrI: IFn = x => '' + x // 정상
interface IStateWithPop extends TState {
population: number
}
type TStateWithPop = IState & { population: number }
인터페이스는 타입을 확장 할 수 있으며 (주의 사항이 몇 가지 있음), 타입도 인터페이스를 확장할 수 있다.
IStateWithPop 과 TStateWithPop은 동일하지만 interface는 유니온 타입 같은 복잡한 타입을 확장하지는 못한다.
유니온 타입은 있지만, 유니온 인터페이스 라는 개념은 없다. interface는 타입을 확장할 수 있지만 Union은 할 수 없다. Union 타입을 확장하는게 필요할 때가 있다. Input과 Output은 별도의 타입이며 이 둘을 하나의 변수명으로 매핑하는 VariableMap 인터페이스를 만들 수 있다.
=> type의 경우는 별도의 타입을 만들지 않는 이상 확장이 불가능하다.
type Input = { ... }
type Output = { ... }
interface VariableMap {
[name: string] : Input | Output
}
// 유니온 타입에 name 속성을 붙인 타입을 만들 수 있다.
type NamedVariable = (Input | Output) & { name : string };
// 튜플과 배열 타입도 type 키워드를 사용해 더 간결하게 표현할 수 있음
type Pair = [number, number]
type StringList = string[];
type NamedNums = [string, ...number[]];
반면 인터페이스는 ‘보강 argument’이 가능하다는 점이 있다. 아래 예제 처럼 속성을 확장하는게 선언 병합이다.
interface IState {
name: string
capital: String
}
interface IState {
population: number
}
const wyoming: TState = {
name: 'Wyoming',
capital: 'Cheyenne',
population: 500000, // 정상!
}
=> 그러면 어떤걸 사용해야 하나요? 코드 내에서 일관되게 인터페이스를 사용하고 있다면 interface를, type을 사용한다면 type을 사용하면 된다. 아직 스타일이 확립되지 않은 프로젝트라면 변경될 가능성이 있다고 봐야한다. API가 변경될 때 사용자가 인터페이스를 통해 새로운 필드를 병합할 수 있어서 편함
출처: 이펙티브 타입스크립트
transaction은 그 자체의 일을 하나로 보고 싶은 작업 단위라고 생각하면 된다. 그러면 그 작업은 그 안의 모든 작업이 다 되던지, 아예 그 작업들이 모두 되지 않던지 둘 중 하나 여야 한다.
classic 한 예로, 한 계좌에서 다른 계좌로 돈을 이체 시킨다고 해보자. 그러기 위해서 source account에서는 돈을 인출하고 목표 계좌에는 입금시켜야 한다. 그 일련의 과정은 모두 정상적으로 이루어져야한다. 만약 중간까지만 진행된다면 돈은 사라지게 되고 이는 매우 안 좋은 상황이다.
현재 modern db transaction들은 또한 다른 일들도 하는데, 예를 들어 다른 사람이 반쯤 쓰고 있는 데이터의 경우에는 접근이 불가능하게 막는다. 하지만 기본 아이디어는 transaction은 어떤 일이 일어나건, 당신이 사용하고 있는 data는 안전한 상태의 데이터라는 걸 보장한다. 즉, 어디서 돈이 인출 되었는데, 다른 계좌로 입금되지 않은 상황을 절대 만들지 않는다는 것이다.
출처: What is a database transactions ?
이 둘이 사용할 때마다 왜 이렇게 헷갈리는지 모르겠다;
splice: (밧줄의 두 끝을 함께 꼬아서) 잇다. 두 끝을 붙이다. -> array 안의 item을 삭제하던지, 교체하던지, 특정 위치에 추가하던지 할 때 사용한다. slice: 조각 -> array 의 부분을 array를 변경하지 않고 알아내려면 slice를 사용!
// Array.splice()
const months = ['Jan', 'March', 'April', 'June']
months.splice(1, 0, 'Feb') // Array.splice(startPosition, deleteCount, item1) -> inserts at 1 위치에!
console.log(months) // Array ["Jan", "Feb", "March", "April", "June"]
months.splice(4, 1, 'May') // 4번째 index의 item 1개를 'May' 로 변경
console.log(months) // ["Jan", "Feb", "March", "April", "May"]
// Array.slice() array 내의 특정 부분을 (원본을 변경하지 않고) 가져올 때 사용
console.log(month.slice(2)) // ["Jan", "Feb", "March"] -> 0 index 부터 2 까지 가져온다.
console.log(month.slice(-2)) // 끝에서 부터 2개 ["April", "June"]
console.log(month.slice(2, -1)) // ["Feb", "March",]