Flow Typechecker
Concepts
-
Typing string literals
Does type as
string:const Foo = 'Foo'; type FooT = typeof Foo; // doesn't do what you'd expectDoes type as the actual value
'Foo':const Foo: 'Foo' = 'Foo'; type FooT = typeof Foo; // but this does, which is a crazy amount of boilerplate for a string literal IMO -
const getAWithoutB = <T: IBeaconMinimum>( arrayA: Array<T>, arrayB: Array<T>, comparator: <T: IBeaconMinimum>(a: T, b: T) => boolean ): Array<T> => differenceWith(arrayA, arrayB, comparator);Note: In
<T: IBeaconMinimum>IBeaconMinimumsets a constraint on the genericT. Prob. due to a bug in FlowType in fat-arrow functions, generics without such a constraint don’t work (2019/01/18) -
// @flow var foo: {| foo: string |} = { foo: "Hello", bar: "World!" }; // Error! -
A Map with a key of type string and another Map as value, where the Map as value has again a string as key and the value can have any type. Now when you are asking, I am not sure where I saw the
*to use for any…const selectLibraryContainerDomain = () => ( state: Map<string, Map<string, *>>, => state.get('library'); -
Suppress flow error on specific line
// $FlowFixMe const hello = "This will not throw a flow error!";in JSX e.g.:
{/* $FlowFixMe */} <LoginContent {...props} /> -
Basic saga exists test
describe('PreviewPage/sagas', () => { it('should have sagas', () => { sagas.map(saga => expect(saga.constructor.name).toBe('GeneratorFunction')); }); }); ...
React
React Elements
type Props = React.ElementProps<typeof SectionList>;`Thunk
redux-thunk actions can be typed as follows:
declare type ThunkAction = (
dispatch: Dispatch<any>,
getState: ReduxState
) => any;
declare type Thunk = (action: ThunkAction) => any;An action which accepts a simple action or a Thunk might be typed like that:
export const myAction = () => (
dispatch: Dispatch<SimpleAction | SomeOtherActionType> & Thunk,
getState: () => *
) => {
// ...
}where SimpleAction is typed as
declare type SimpleAction = $Exact<StandardAction>;Issues
-
Buggy intersection type
&Will throw errors:
type AllProps = StateProps & DispatchProps;Will work as expected:
type AllProps = {| ...StateProps, ...DispatchProps |};(when used in the
connectcall ofreact-redux)
Declaration files
- Types, Interfaces, Classes
- Use
declareeach time - Add
exportright afterdeclareif it should be available for import.
Example:
declare module 'react-native-background-geolocation-android' {
declare type LogLevel = 0 | 1 | 2 | 3 | 4 | 5;
declare export type LogLevel = 0 | 1 | 2 | 3 | 4 | 5;
declare interface DeviceSettings {
isIgnoringBatteryOptimizations(): Promise<boolean>;
extras?: Object;
}
declare export interface Device {
layout?: string;
}
declare export default class BackgroundGeolocation {
static LOG_LEVEL_OFF: LogLevel;
static addListener(
event: string,
success: Function,
failure?: Function
): void;
}
}Differences between TypeScript and Flow
This article summarizes it nicely.
Companion Object Pattern
- type and value have different namespaces and can e.g. be imported at once.
See also Programming TypeScript book on page 140.
(TS only) Refining the type of an array
Example: filter function
filter(callbackfn: (value: T, index: number, array: Array<T>) => any, thisArg?: any): Array<T>;filter definition in TypeScript:
interface Array<T> {
filter<S extends T>(callbackfn: (value: T, index: number) => value is S): S[];
}- In TS you can refine the type of an array (i.e. narrow type
TtoS) by filtering it. Here it is described even more. - Flow can’t model this. The output there is
Array<T>-> The same as the type at the beginning. - This is being discussed in this thread.
(Flow only) Relationship between types
-
covariance vs. contravariance vs. invariance
- e.g. extends: In
K extends keyof T,"extends" means a type with **covariant** relationship withkeyof T`.
- e.g. extends: In
- Flow has specific syntax for programmers to specify variance for own data types.
- TS found a balance between type-safety and practicability.
Discuss on Twitter ● Improve this article: Edit on GitHub