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
That said, if there is opportunity to narrow a type with an explicit type declaration, it should be taken.
51
+
52
+
##### `as const`, `satisfies` can be used to further narrow inferred types
53
+
54
+
- Link to `as const` entry
55
+
-`satisfies`: coming soon
56
+
57
+
##### When initializing an empty container type, provide a type annotation
58
+
59
+
- The compiler cannot arbitrarily restrict the range of types that can be inserted into the container, and therefore needs to assume the widest type.
60
+
61
+
```ts
62
+
const tokens = []; // 🚫 Type 'any[]'
63
+
const tokens:string[] = []; // ✅ Type 'string[]'
64
+
```
65
+
66
+
#### Generic parameters can be used to narrow types
67
+
68
+
- A type with generic parameter(s) that can be omitted may sometimes be written to correctly infer the parameter's type, but it may just as often use the widest possible type that satisfies the generic constraint as a default fallback value. This fallback can sometimes be `any`.
>(); // Type 'jest.Mock<NetworkConfiguration | undefined, [networkClientId: string]>'
103
+
```
104
+
105
+
##### Type guards and null checks can be used to improve type inference
106
+
107
+
TypeScript types are erased (https://en.wikipedia.org/wiki/Type_erasure) during compilation. This means there is no built-in mechanism for performing runtime type checks.
108
+
109
+
A popular method for runtime checks is to verify that properties exist on an object. You can use user-defined type guards to accomplish this:
110
+
111
+
```ts
112
+
function isSomeInterface(x:unknown):xisSomeInterface {
113
+
return'name'inx
114
+
&&typeofx.name==='string'
115
+
&&'length'inx
116
+
&&typeofx.length==='number';
117
+
}
118
+
119
+
function f(x:SomeInterface|SomeOtherInterface) {
120
+
if (isSomeInterface(x)) {
121
+
console.log(x.name); // Cool!
122
+
}
123
+
}
124
+
```
125
+
126
+
##### For functions and methods, provide explicit return types
6
127
7
128
Although TypeScript is capable of inferring return types, adding them explicitly makes it much easier for the reader to see the API from the code alone and prevents unexpected changes to the API from emerging.
@@ -39,3 +160,113 @@ async function removeAccount(address: Hex): Promise<KeyringControllerState> {
39
160
returnthis.fullUpdate();
40
161
}
41
162
```
163
+
164
+
- Provide an explanation via comment when performing explicit type assertions or overriding related eslint rules (e.g. forbid `any`, forbid `non-null assertions`)
165
+
166
+
### C. Type Assertions (`as`, `!`)
167
+
168
+
`as` assertions and non-nullability assertions (`!`) are unsafe. They override type-checked and inferred types with user-supplied types that suppress compiler errors.
169
+
170
+
While TypeScript will throw type errors against some unsafe or structurally unsound type assertion scenarios, it will generally accept the user-supplied type without type-checking. This can cause silent failures where errors are suppressed.
171
+
172
+
- TypeScript and eslint will raise warnings against some unsafe or structurally unsound type assertions, but this capability is limited.
173
+
- Type assertions make the code brittle against changes,
174
+
175
+
-`as` assertions intended to exclude an empty/nullable type (e.g. `| undefined`) can be replaced with a nullish coalescing operator providing an acceptable fallback empty value that doesn't pollute the variable's type signature.
176
+
177
+
```ts
178
+
arr: string[] |undefined
179
+
(arrasstring[]) // 🚫
180
+
(arr?? []) // ✅
181
+
182
+
s: string|undefined
183
+
(sasstring) // 🚫
184
+
(s??'') // ✅
185
+
```
186
+
187
+
#### Acceptable use cases of `as`
188
+
189
+
##### To prevent or fix `any` usage
190
+
191
+
- At least we get working intellisense, autocomplete.
192
+
- We also get an indication of the expected type as intended by the author.
193
+
- For type assertions to an incompatible shape, use `as unknown as` as a last resort.
- In general, using `any` in this context is not harmful in the same way that it is in other contexts, as the `any` types only are not directly assigned to any specific variable, and only function as constraints.
262
+
- That said, narrower constraints provide better type safety and intellisense.
263
+
264
+
##### Catching errors
265
+
266
+
-`catch` only accepts `any` and `unknown` as the error type.
267
+
- Recommended: Use `unknown` with type guards like `isJsonRpcError`.
268
+
- Avoid typing an error object with `any` if it is used elsewhere instead of just being thrown.
269
+
270
+
##### In tests, for mocking or to intentionally break features
271
+
272
+
- Recommended: Provide accurate typing wherever possible.
0 commit comments