-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterface.html
More file actions
174 lines (155 loc) · 5.64 KB
/
interface.html
File metadata and controls
174 lines (155 loc) · 5.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>노재원의 블로그</title>
</head>
<body>
<h1>인터페이스</h1>
<h2>Before</h2>
<pre>
interface BASIC_INTERFACE {
value: string
}
interface OPTIONAL_INTERFACE {
value?: number
label?: string
aa: number
}
interface READ_ONLY_INTERFACE {
readonly value: number
}
interface FUNCTION_INTERFACE {
(width: number, height: number): boolean
}
interface NORMAL_CLASS_INTERFACE {
aa: number,
getAa(): number
}
interface CONSTRUCTOR {
new (width: number, height: number): NORMAL_CLASS_INTERFACE
}
const basic = (obj: BASIC_INTERFACE) => {
return obj;
};
const optional = (obj: OPTIONAL_INTERFACE) => {
const a: OPTIONAL_INTERFACE = JSON.parse(JSON.stringify(obj));
delete a.value;
return a;
}
const readOnly = (obj: READ_ONLY_INTERFACE) => {
const a: READ_ONLY_INTERFACE = JSON.parse(JSON.stringify(obj));
// delete a.value; // The operand of a 'delete' operator cannot be a read-only property.
// a.value = 1; // const 또는 readonly 변수에 할당시도
return a;
}
const func: FUNCTION_INTERFACE = (width: number, height: number): boolean => { // interface에서 return type이 명시 되었기 때문에 써도 안써도 꼭 boolean을 return해야함.
return width > height;
}
class Normal implements NORMAL_CLASS_INTERFACE {
constructor() {}
aa: number = 1
getAa():number {
return this.aa;
}
}
class ConstructorTest implements NORMAL_CLASS_INTERFACE {
constructor(width: number, height: number) {}
aa: number = 1
getAa():number {
return this.aa;
}
}
// hybrid type 다 섞는다... 라이브러리의 코드나 외부 api의 payload로 쓰이는 것이 아니라면... 직접 작성은 지양하는게 좋겠음.
// interface를 interface로 확장 할 수 있으며 interface를 class로 확장 할 수 있다.
// 단순 interface가 private, protected를 지정할 수 없다면 class를 상속받은 interface는 그것까지 딸려옴.
const BASIC: BASIC_INTERFACE = { value: 'test' };
const OPTIONAL: OPTIONAL_INTERFACE = { value: 1, aa: 2 };
const READ_ONLY: READ_ONLY_INTERFACE = { value: 22 };
const nomalInstance = new Normal();
const constructorTestInstance = ((c: CONSTRUCTOR, width: number, height: number) => new ConstructorTest(width, height))(ConstructorTest, 10, 10);
const ctt: CONSTRUCTOR = class Cti implements NORMAL_CLASS_INTERFACE { // 더 쉬운 방
constructor(width: number, height: number) {}
aa: number = 1
getAa():number {
return this.aa;
}
}
const ctti: NORMAL_CLASS_INTERFACE = new ctt(10, 10);
basic(BASIC); // { value: "test" }
optional(OPTIONAL); // { aa: 2 }
readOnly(READ_ONLY); // { value: 22 }
// basic({value: "11", dd: 1}) // Argument of type '{ value: string; dd: number; }' is not assignable to parameter of type 'BASIC_INTERFACE'. Object literal may only specify known properties, and 'dd' does not exist in type 'BASIC_INTERFACE'.
func(10, 100); // false
nomalInstance.getAa(); // 1
constructorTestInstance.getAa(); // 1
ctti.getAa(); // 1
</pre>
<h2>After</h2>
<pre>
const basic = (obj) => {
return obj;
};
const optional = (obj) => {
const a = JSON.parse(JSON.stringify(obj));
delete a.value;
return a;
};
const readOnly = (obj) => {
const a = JSON.parse(JSON.stringify(obj));
// delete a.value; // The operand of a 'delete' operator cannot be a read-only property.
// a.value = 1; // const 또는 readonly 변수에 할당시도
return a;
};
const func = (width, height) => {
return width > height;
};
class Normal {
constructor() {
this.aa = 1;
}
getAa() {
return this.aa;
}
}
class ConstructorTest {
constructor(width, height) {
this.aa = 1;
}
getAa() {
return this.aa;
}
}
const BASIC = { value: 'test' };
const OPTIONAL = { value: 1, aa: 2 };
const READ_ONLY = { value: 22 };
const nomalInstance = new Normal();
const constructorTestInstance = ((c, width, height) => new ConstructorTest(width, height))(ConstructorTest, 10, 10);
const ctt = class Cti {
constructor(width, height) {
this.aa = 1;
}
getAa() {
return this.aa;
}
};
const ctti = new ctt(10, 10);
basic(BASIC); // { value: "test" }
optional(OPTIONAL); // { aa: 2 }
readOnly(READ_ONLY); // { value: 22 }
// basic({value: "11", dd: 1}) // Argument of type '{ value: string; dd: number; }' is not assignable to parameter of type 'BASIC_INTERFACE'. Object literal may only specify known properties, and 'dd' does not exist in type 'BASIC_INTERFACE'.
func(10, 100); // false
nomalInstance.getAa(); // 1
constructorTestInstance.getAa(); // 1
ctti.getAa(); // 1
</pre>
<p>인터페이스 자체는 transpile과정에서 사용되고 JS로 변환되지는 않는다.</p>
<p>Indexable Types 에 대해서는 아직까지는 우려되는 점만 눈에 띈다.</p>
<p>모든 property가 같은 type으로 return되도록 하는 점.</p>
<p>그것을 우회하기 위해서 [index: string]: number | string; index쪽의 타입을 유니언으로 걸어야 하는점. (빈대 잡으려다 초가삼간 태우는 것 같아보임..)</p>
<p>hybrid type 다 섞는다... 라이브러리의 코드나 외부 api의 payload로 쓰이는 것이 아니라면... 직접 작성은 지양하는게 좋겠음.</p>
<p>interface를 interface로 확장 할 수 있으며 interface를 class로 확장 할 수 있다.</p>
<p>단순 interface가 private, protected를 지정할 수 없다면 class를 상속받은 interface는 그것까지 딸려옴.</p>
<p>다중 확장을 통해 다중 상속이 가능하기에 interface라 명명했을까? abstract class 이상의 기능을 하는(다중 상속이 필요한) 상황이 많이 필요할까..? 필요하다 하여도 다중 상속으로 구현해야 하는가??</p>
</body>
</html>