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
@@ -18,8 +18,9 @@ I'm open to contributions and comments.
18
18
| expressiveness | great (since TS @ 2.1) | great |
19
19
| type safety | great (TS @ 2.0) | great |
20
20
| typings for public libraries | plenty of well mainained typings | a handful of mostly incomplete typings |
21
-
| unique features | autocomplete for object construction, huge library of mainained Typings, `readonly` properties, `never` type, namespacing | variance, existential types `*`, testing all potential code-paths when typings not declared for maximum inference, `$Diff<A, B>` type |
22
-
| ecosystem flexibility | no extensions as of yet | no extensions as of yet |
21
+
| unique features | <ul><li>autocomplete for object construction</li><li>declarable `this` in functions (typing binding)</li><li>large library of mainained typings</li><li>more flexible type mapping via iteration</li><li>namespacing</li></ul> | <ul><li>variance</li><li>existential types `*`</li><li>testing potential code-paths when types not declared for maximum inference</li><li>`$Diff<A, B>` type</li></ul> |
22
+
| ecosystem flexibility | work in progress | no extensions |
23
+
| programmatic hooking | architecture prepared, work in progress | work in progress |
23
24
24
25
# Differences in syntax
25
26
@@ -122,28 +123,32 @@ declare module "*.css" {
122
123
123
124
## Exact/Partial Object Types
124
125
125
-
By default objects in Flow are not strict (exact), whereas in TypeScript they are always strict, unless set as partial.
126
+
By default objects in Flow are not exact (can contain more properties than declared), whereas in TypeScript they are always exact (must contain only declared properties).
126
127
127
128
### Flow
128
129
129
130
When using flow, `{ name: string }` only means “an object with **at least** a name property”.
130
131
131
132
```js
132
-
type StrictUser= {| name: string, age: number |};
133
+
type ExactUser= {| name: string, age: number |};
133
134
type User = { name: string, age: number };
134
-
type PartialUser= $Shape<User>;
135
+
type OptionalUser= $Shape<User>;// all properties become optional
135
136
```
136
137
137
138
### TypeScript
138
139
140
+
TypeScript is more strict here, in that if you want to use a property which is not declared, you must explicitly say so by defining the indexed property. You will be allowed to use custom properties, but will have to access them through the bracket access syntax, i.e. UserInstance['someProperty']. At the moment, you cannot define "open" (non-exact) types using TypeScript. This is mostly a design decision as it forces you to write the typings upfront.
141
+
139
142
```js
140
-
type StrictUser = { name: string, age: number };
141
-
type PartialUser = Partial<{ name: string, age: number }>;
143
+
type ExactUser = { name: string, age: number };
144
+
type User = { name: string, age: number, [otherProperty: any] };
145
+
type OptionalUser = Partial<{ name: string, age: number }>; // all properties become optional
function getProp<KextendskeyofPropsType>(key:K):PropsType[K] {
222
+
function getProp<T>(key:KeysOfProps):T {
214
223
returnprops[key]
215
224
}
216
225
```
217
226
218
-
## Mapped Types
219
-
220
-
TODO: use an example which does the same
227
+
## Records
221
228
222
229
### Flow
223
230
224
231
```js
225
-
type ExtractCodomain =<V>(v: () =>V) =>V;
226
-
function f<O>(o:O): $ObjMap<O, ExtractCodomain>;
232
+
type $Record<T, U>= {[key: $Enum<T>]:U}
233
+
type SomeRecord = $Record<{ a: number }, string>
227
234
```
228
235
229
236
### TypeScript
230
237
231
238
```ts
232
-
type Partial<T> = {
233
-
[Pin keyof T]?:T[P];
234
-
};
239
+
typeSomeRecord=Record<{ a:number }, string>
235
240
```
236
241
237
-
#Same syntax
242
+
## Lookup Types
238
243
239
-
Most of the syntax of Flow and TypeScript is the same. TypeScript is more expressive for certain use-cases (advanced mapped types with keysof, readonly properties), and Flow is more expressive for others (e.g. `$Diff`).
244
+
### Flow
240
245
241
-
## optional parameters
246
+
```js
247
+
typeA= {
248
+
thing:string
249
+
}
242
250
243
-
### Flow and TypeScript
251
+
typelookedUpThing=$PropertyType<A, 'thing'>
252
+
```
244
253
245
-
```js
246
-
function(a?:string) {}
254
+
### TypeScript
255
+
256
+
```ts
257
+
typeA= {
258
+
thing:string
259
+
}
260
+
261
+
typelookedUpThing=typeofA['thing']
247
262
```
248
263
249
-
## Flow's "mixed" type
264
+
## Mapped Types / Foreach Property
250
265
251
-
Flow's `mixed` type is simply a union of all the basic types (string, number, boolean) without their Object versions.
266
+
### Flow
267
+
268
+
```js
269
+
typeInputType= { hello:string };
270
+
typeMappedType=$ObjMap<InputType, number>;
271
+
```
272
+
273
+
### TypeScript
252
274
253
-
The TypeScript equivalent should be:
275
+
A bit more flexibility here, as you have access to each individual key name and can combine with Lookup types and even do simple transformations.
a = { b:'something-else' } // ERROR: reassignment is NOT allowed in Flow
296
+
```
297
+
298
+
### TypeScript
266
299
267
300
```ts
268
-
// Compiled with --strictNullChecks
269
-
function validateEntity(e:Entity?) {
270
-
// Throw exception if e is null or invalid entity
301
+
typeA= {
302
+
readonly b:string
271
303
}
272
304
273
-
function processEntity(e:Entity?) {
274
-
validateEntity(e);
275
-
let s =e!.name; // Assert that e is non-null and access name
305
+
let a:A= { b: 'something' }
306
+
a.b='something-else'; // ERROR
307
+
a= { b: 'something-else' } // OK: reassignment is alowed in TypeScript
308
+
```
309
+
310
+
## "Impossible flow" type
311
+
312
+
### Flow
313
+
314
+
`empty`
315
+
316
+
```js
317
+
functionreturnsImpossible() {
318
+
thrownewError();
276
319
}
320
+
321
+
// type of returnsImpossible() is 'empty'
277
322
```
278
323
279
-
## Lookup Types
324
+
### TypeScript
325
+
326
+
`never`
280
327
281
328
```ts
282
-
typeA= {
283
-
thing:string
329
+
function returnsImpossible() {
330
+
thrownewError();
284
331
}
285
332
286
-
typelookedUpThing=typeofA['thing']
333
+
//type of returnsImpossible() is 'never'
287
334
```
288
335
289
-
## Read-only Types
336
+
# Same syntax
337
+
338
+
Most of the syntax of Flow and TypeScript is the same. TypeScript is more expressive for certain use-cases (advanced mapped types with keysof, readonly properties), and Flow is more expressive for others (e.g. `$Diff`).
339
+
340
+
## optional parameters
341
+
342
+
### Flow and TypeScript
343
+
344
+
```js
345
+
function(a?:string) {}
346
+
```
347
+
348
+
# TypeScript-only concepts
349
+
350
+
## Declarable arbitrary `this` in functions (outside of objects)
290
351
291
352
```ts
292
-
typeA= {
293
-
readonly b:string
353
+
function something(this: { hello:string }, firstArg:string) {
0 commit comments