Skip to content

Instantly share code, notes, and snippets.

@kujon
Created June 6, 2018 16:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kujon/c84b47573af7900fd9467f2d022f2427 to your computer and use it in GitHub Desktop.
Save kujon/c84b47573af7900fd9467f2d022f2427 to your computer and use it in GitHub Desktop.
react-url-query typings
declare module 'react-url-query' {
import * as React from 'react';
type Dictionary<T = string> = {
[key: string]: T;
};
export const UrlQueryParamTypes: {
number: 'number';
string: 'string';
// object: 'object';
// array: 'array';
json: 'json';
date: 'date';
boolean: 'boolean';
numericObject: 'numericObject';
numericArray: 'numericArray';
};
export const UrlUpdateTypes: {
replace: 'replace';
replaceIn: 'replaceIn';
push: 'push';
pushIn: 'pushIn';
};
export type CustomParamType<T> = {
encode: (value: T) => string | undefined;
decode: (value: string | undefined, defaultValue: T) => T;
};
export type ParamType<T> = keyof typeof UrlQueryParamTypes | CustomParamType<T>;
export type UrlPropsQueryConfig<U> = {
[K in keyof U]: {
type: ParamType<U[K]>;
queryParam?: string;
defaultValue?: U[K];
decode?: (encodedValue: string, defaultValue: U[K]) => U[K];
}
};
export type AddUrlOptions<U> = { urlPropsQueryConfig: UrlPropsQueryConfig<U> };
// Diff / Omit taken from https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-311923766
type Diff<T extends string, U extends string> = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
export function addUrlProps<U>(
options: AddUrlOptions<U>
): <P extends U>(Component: React.ComponentType<P>) => React.ComponentType<Omit<P, keyof U>>;
export type UrlReplaceInAction<U, K extends keyof U> = {
type: string;
payload: {
queryParam: K;
encodedValue: string;
decodedValue: U[K];
type: ParamType<U[K]>;
};
meta: {
updateType: typeof UrlUpdateTypes.replaceIn;
urlQuery: true;
};
};
export function urlReplaceInAction<U>(
actionType: string,
paramName: keyof U,
paramType: ParamType<U[keyof U]>
): (paramValue: U[keyof U]) => UrlReplaceInAction<U, keyof U>;
export type UrlReplaceAction<U, K extends keyof U> = {
type: string;
meta: {
updateType: typeof UrlUpdateTypes.replace;
urlQuery: true;
};
payload: {
encodedQuery: { [k in K]: string };
decodedQuery: U;
};
};
/** Changes URL params without adding to the history stack */
export function urlReplaceAction<U>(
actionType: string,
encodeQuery?: (query: U) => { [K in keyof U]: string },
updateType?: typeof UrlUpdateTypes.replace
): (params: U) => UrlReplaceAction<U, keyof U>;
/** Changes URL params AND adds to the history stack */
export function urlPushAction<U>(
actionType: string,
encodeQuery?: (query: U) => { [K in keyof U]: string },
updateType?: typeof UrlUpdateTypes.replace
): (params: U) => UrlReplaceAction<U, keyof U>;
export function RouterToUrlQuery(): any;
export function urlQueryMiddleware(options?: { shortcircuit?: boolean; reducer?: any }): any;
export function decode<T>(type: ParamType<T>, encodedValue: string, defaultValue?: any): T;
export type UrlQueryConfig = {
addUrlChangeHandlers: boolean;
addRouterParams: boolean;
// FIXME: Implement this.
// changeHandlerName: propName =>
// `onChange${propName[0].toUpperCase()}${propName.substring(1)}`,
// FIXME: THIS IS A LIE!
history: {
location: Dictionary<string | number>;
};
entrySeparator: string;
keyValSeparator: string;
// FIXME: This could be a lie.
readLocationFromStore(state: object): Location | undefined;
};
export function encode<T>(type: ParamType<T>, decodedValue: T): string;
export const urlQueryConfig: UrlQueryConfig;
// FIXME: The commented out versions are what represents reality.
// The uncommented ones represent what's useful to us.
// export function urlQueryDecoder<T>(config: UrlPropsQueryConfig<T>): (props: { [index: string]: string; }) => T;
// export function urlQueryEncoder<T>(config: UrlPropsQueryConfig<T>): (props: T) => { [index: string]: string; };
export function urlQueryDecoder<T>(
config: UrlPropsQueryConfig<T>
): (props: Partial<{ [K in keyof T]: string }>) => T;
export function urlQueryEncoder<T>(config: UrlPropsQueryConfig<T>): (props: T) => { [K in keyof T]: string };
export function configureUrlQuery(config: Partial<UrlQueryConfig>): void;
}
declare module 'react-url-query/es/urlQueryDecoder';
@kujon
Copy link
Author

kujon commented Jun 6, 2018

Not happy with this enough to include it in DefinitelyTyped, but feel free to use it as a template.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment