Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Typescript typing #50

Merged
merged 2 commits into from
Mar 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ build/Release
node_modules

# distribution
dist
dist

.DS_Store
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@
},
"dependencies": {
"invariant": "^2.2.2"
}
},
"typings": "typings/index.d.ts"
}
119 changes: 119 additions & 0 deletions typings/__tests__/ImmutablePropTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import * as React from 'react';
import * as ImmutablePropTypes from 'react-immutable-proptypes';
import * as Immutable from 'immutable';

// test primitive types
export const propTypesPrimitives = {
oldListTypeChecker: React.PropTypes.instanceOf(Immutable.List),
anotherWay: ImmutablePropTypes.list,
requiredList: ImmutablePropTypes.list.isRequired,
mapsToo: ImmutablePropTypes.map,
evenIterable: ImmutablePropTypes.iterable,
orderedMapYes: ImmutablePropTypes.orderedMap,
setYes: ImmutablePropTypes.set,
orderedSetYes: ImmutablePropTypes.orderedSet,
stackYes: ImmutablePropTypes.stack,
seqYes: ImmutablePropTypes.seq,
recordYes: ImmutablePropTypes.record,
};


// Test Contains
export const containsTest = {
aMap: ImmutablePropTypes.contains({
aList: ImmutablePropTypes.contains({
0: React.PropTypes.number,
1: React.PropTypes.string,
2: React.PropTypes.number.isRequired,
}).isRequired,
})
};

// Test MapOf
export const aMap = ImmutablePropTypes.mapOf(
React.PropTypes.any, // validation for values
ImmutablePropTypes.mapContains({ // validation for keys
a: React.PropTypes.number.isRequired,
b: React.PropTypes.string
})
);

// validation for keys (same is in mapOf)
const mapVal = ImmutablePropTypes.mapContains({ // validation for keys
a: React.PropTypes.number.isRequired,
b: React.PropTypes.string
});

// Test orderedMapOf
export const aOrderedMapOf = ImmutablePropTypes.orderedMapOf(
React.PropTypes.any,
mapVal
);


// Test listOf
const aListOf = ImmutablePropTypes.listOf(
React.PropTypes.number, // validation for values
);

// test compatibility with react types
if (aListOf === React.PropTypes.arrayOf(React.PropTypes.number)) {
alert('should be comparable with reacht types');
}

// Test orderedSetOf
export const aOrderedSetOf = ImmutablePropTypes.orderedSetOf(
React.PropTypes.number, // validation for values
);

// Test stackOf
export const aStackOf = ImmutablePropTypes.stackOf(
React.PropTypes.string, // validation for values
);

// Test iterableOf
export const aIterableOf = ImmutablePropTypes.iterableOf(
React.PropTypes.string, // validation for values
);


// Test recordOf
export const aRecordOf = ImmutablePropTypes.recordOf({
keyA: React.PropTypes.string,
keyB: ImmutablePropTypes.seq.isRequired
});

// Test mapContains
export const aMapContains = ImmutablePropTypes.mapContains({
aList: ImmutablePropTypes.list.isRequired,
});

// Test shape
export const aSahpe = ImmutablePropTypes.shape({
aList: ImmutablePropTypes.list.isRequired,
});


// Test with component

React.createClass<{}, {}>({
propTypes: {
myRequiredImmutableList: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
someNumberProp: React.PropTypes.number.isRequired
})
).isRequired
},
render: () => { return null; }
});

React.createClass<{}, {}>({
propTypes: {
myRequiredImmutableList: ImmutablePropTypes.listOf(
ImmutablePropTypes.contains({
someNumberProp: React.PropTypes.number.isRequired
})
).isRequired
},
render: () => { return null; }
});
124 changes: 124 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Typescript typings for `react-immutable-proptypes`

/** Copy of `React.PropTypes`'s `Validator` */
interface Validator<T> {
(object: T, key: string, componentName: string, ...rest: any[]): Error | null;
}

/** Copy of `React.PropTypes`'s `Requireable<T>` */
interface Requireable<T> extends Validator<T> {
isRequired: Validator<T>;
}

/** .
* Modification of `React.PropTypes`'s `ValidationMap<T>` type
*
* `type ValidationMap<T> = { [K in keyof T]?: Validator<T> };`
*
* original seemd too generic, since it allowed stings and numbers as args
*/
type ValidatorMap<T> = { [key: string]: Validator<T> };

/** combination of */
type ValidaterOrValidatorMap = Validator<any> | ValidatorMap<any>


declare module 'react-immutable-proptypes' {
/**
* `ImmutablePropTypes.listOf` is based on `React.PropTypes.array` and
* is specific to `Immutable.List`
*/
function listOf(typeChecker: ValidaterOrValidatorMap): Requireable<any>;

/**
* `ImmutablePropTypes.mapOf` allows you to control both map values and keys
* (in `Immutable.Map`, keys could be anything including another Immutable collections).
*
*
* It accepts two arguments - first one for values, second one for keys (_optional_).
*
* If you are interested in validation of keys only, just pass `React.PropTypes.any` as
* the first argument.
*/
function mapOf(valuesTypeChecker: Requireable<any>, keysTypeChecker?: Requireable<any>): Requireable<any>;

/**
* `ImmutablePropTypes.orderedMapOf` is basically the same as `mapOf`,
* but it is specific to `Immutable.OrderedMap`.
*/
function orderedMapOf(valuesTypeChecker: Requireable<any>, keysTypeChecker: Requireable<any>): Requireable<any>;

/**
* `ImmutablePropTypes.setOf` is basically the same as `listOf`,
* but it is specific to `Immutable.Set`.
*/
function setOf(typeChecker: Requireable<any>): Requireable<any>;

/**
* `ImmutablePropTypes.orderedSetOf` is basically the same as `listOf`,
* but it is specific to `Immutable.OrderedSet`.
*/
function orderedSetOf(typeChecker: Requireable<any>): Requireable<any>;

/**
* `ImmutablePropTypes.stackOf` is basically the same as `listOf`,
* but it is specific to `Immutable.Stack`.
*/
function stackOf(typeChecker: Requireable<any>): Requireable<any>;

/**
* `ImmutablePropTypes.iterableOf` is the generic form of `listOf`/`mapOf`.
* It is useful when there is no need to validate anything other than Immutable.js
* compatible (ie. `Immutable.Iterable`).
*
* Continue to use `listOf` and/or `mapOf` when you know the type.
*/
function iterableOf(typeChecker: Requireable<any>): Requireable<any>;

/**
* `ImmutablePropTypes.recordOf` is like contains,
* except it operates on `Record` properties.
*/
function recordOf(recordKeys: ValidaterOrValidatorMap): Requireable<any>;

/**
* `ImmutablePropTypes.mapContains` is based on `React.PropTypes.shape` and will only work
* with `Immutable.Map`.
*/
function shape(shapeTypes: ValidaterOrValidatorMap): Requireable<any>;

/**
* ImmutablePropTypes.contains (formerly `shape`) is based on `React.PropTypes.shape`
* and will try to work with any `Immutable.Iterable`.
*
* In my usage it is the most used validator, as I'm often trying to validate that a `map`
* has certain properties with certain values.
* @return {Requireable<any>}
*/
function contains(shapeTypes: ValidaterOrValidatorMap): Requireable<any>;

/**
* `ImmutablePropTypes.mapContains` is based on `React.PropTypes.shape` and will only work
* with `Immutable.Map`.
*/
function mapContains(shapeTypes: ValidaterOrValidatorMap): Requireable<any>;

/** checker for `Immutable.List.isList` */
const list: Requireable<any>;
/** checker for `Immutable.Map.isMap` */
const map: Requireable<any>;
/** checker for `Immutable.OrderedMap.isOrderedMap` */
const orderedMap: Requireable<any>;
/** checker for `Immutable.Set.isSet` */
const set: Requireable<any>;
/** checker for `Immutable.OrderedSet.isOrderedSet` */
const orderedSet: Requireable<any>;
/** checker for `Immutable.Stack.isStack` */
const stack: Requireable<any>;
/** checker for `Immutable.Seq.isSeq` */
const seq: Requireable<any>;
/** checker for `instanceof Record` */
const record: Requireable<any>;
/** checker for `Immutable.Iterable.isIterable` */
const iterable: Requireable<any>;
}