You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
Copy file name to clipboardExpand all lines: pages/Interfaces.md
+59-2Lines changed: 59 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ In TypeScript, interfaces fill the role of naming these types, and are a powerfu
9
9
The easiest way to see how interfaces work is to start with a simple example:
10
10
11
11
```ts
12
-
function printLabel(labelledObj: {label:string}) {
12
+
function printLabel(labelledObj: {label:string}) {
13
13
console.log(labelledObj.label);
14
14
}
15
15
@@ -20,6 +20,7 @@ printLabel(myObj);
20
20
The type-checker checks the call to `printLabel`.
21
21
The `printLabel` function has a single parameter that requires that the object passed in has a property called `label` of type string.
22
22
Notice that our object actually has more properties than this, but the compiler only checks that *at least* the ones required are present and match the types required.
23
+
There are some cases where TypeScript isn't as lenient, which we'll cover in a bit.
23
24
24
25
We can write the same example again, this time using an interface to describe the requirement of having the `label` property that is a string:
25
26
@@ -82,7 +83,7 @@ interface SquareConfig {
82
83
width?:number;
83
84
}
84
85
85
-
function createSquare(config:SquareConfig): {color:string; area:number} {
86
+
function createSquare(config:SquareConfig): {color:string; area:number} {
86
87
let newSquare = {color: "white", area: 100};
87
88
if (config.color) {
88
89
// Error: Property 'collor' does not exist on type 'SquareConfig'
In our first example using interfaces, TypeScript let us pass `{ size: number; label: string; }` to something that only expected a `{ label: string; }`.
104
+
We also just learned about optional properties, and how they're useful when describing so-called "option bags".
105
+
106
+
However, combining the two naively would let you to shoot yourself in the foot the same way you might in JavaScript.
107
+
For example, taking our last example using `createSquare`:
108
+
109
+
```ts
110
+
interfaceSquareConfig {
111
+
color?:string;
112
+
width?:number;
113
+
}
114
+
115
+
function createSquare(config:SquareConfig): { color:string; area:number } {
116
+
// ...
117
+
}
118
+
119
+
let mySquare =createSquare({ colour: "red", width: 100 });
120
+
```
121
+
122
+
Notice the given argument to `createSquare` is spelled *`colour`* instead of `color`.
123
+
In plain JavaScript, this sort of thing fails silently.
124
+
125
+
You could argue that this program is correctly typed, since the `width` properties are compatible, there's no `color` property present, and the extra `colour` property is insignificant.
126
+
127
+
However, TypeScript takes the stance that there's probably a bug in this code.
128
+
Object literals get special treatment and undergo *excess property checking* when assigning them to other variables, or passing them as arguments.
129
+
If an object literal has any properties that the "target type" doesn't have, you'll get an error.
130
+
131
+
```ts
132
+
// error: 'colour' not expected in type 'SquareConfig'
133
+
let mySquare =createSquare({ colour: "red", width: 100 });
134
+
```
135
+
136
+
Getting around these checks is actually really simple.
137
+
The best and easiest method is to just use a type assertion:
138
+
139
+
```ts
140
+
let mySquare =createSquare({ colour: "red", width: 100 } asSquareConfig);
141
+
```
142
+
143
+
Another approach, which might be a bit surprising, is to assign the object to another variable:
144
+
145
+
```ts
146
+
let squareOptions = { colour: "red", width: 100 };
147
+
let mySquare =createSquare(squareOptions);
148
+
```
149
+
150
+
Since `squareOptions` won't undergo excess property checks, the compiler won't give you an error.
151
+
152
+
Keep in mind that for simple code like above, you probably shouldn't be trying to "get around" these checks.
153
+
For more complex object literals that have methods and hold state, you might need to keep these techniques in mind, but a majority of excess property errors are actually bugs.
154
+
That means if you're running into excess property checking problems for something like option bags, you might need to revise some of your type declarations.
155
+
In this instance, if it's okay to pass an object with both a `color` or `colour` property to `createSquare`, you should fix up the definition of `SquareConfig` to reflect that.
156
+
100
157
# Function Types
101
158
102
159
Interfaces are capable of describing the wide range of shapes that JavaScript objects can take.
0 commit comments