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 definition #52

Merged
merged 1 commit into from Apr 6, 2019
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
168 changes: 84 additions & 84 deletions bench.js
@@ -1,95 +1,95 @@
'use strict';
const Benchmark = require('benchmark');
const m = require('.');
const dotProp = require('.');

const suite = new Benchmark.Suite();

suite
.add('get', () => {
const f1 = {foo: {bar: 1}};
m.get(f1);
f1[''] = 'foo';
m.get(f1, '');
m.get(f1, 'foo');
m.get({foo: 1}, 'foo');
m.get({foo: null}, 'foo');
m.get({foo: undefined}, 'foo');
m.get({foo: {bar: true}}, 'foo.bar');
m.get({foo: {bar: {baz: true}}}, 'foo.bar.baz');
m.get({foo: {bar: {baz: null}}}, 'foo.bar.baz');
m.get({foo: {bar: 'a'}}, 'foo.fake');
m.get({foo: {bar: 'a'}}, 'foo.fake.fake2');
m.get({'\\': true}, '\\');
m.get({'\\foo': true}, '\\foo');
m.get({'bar\\': true}, 'bar\\');
m.get({'foo\\bar': true}, 'foo\\bar');
m.get({'\\.foo': true}, '\\\\.foo');
m.get({'bar\\.': true}, 'bar\\\\.');
m.get({'foo\\.bar': true}, 'foo\\\\.bar');

const f2 = {};
Object.defineProperty(f2, 'foo', {
const fixture1 = {foo: {bar: 1}};
dotProp.get(fixture1);
fixture1[''] = 'foo';
dotProp.get(fixture1, '');
dotProp.get(fixture1, 'foo');
dotProp.get({foo: 1}, 'foo');
dotProp.get({foo: null}, 'foo');
dotProp.get({foo: undefined}, 'foo');
dotProp.get({foo: {bar: true}}, 'foo.bar');
dotProp.get({foo: {bar: {baz: true}}}, 'foo.bar.baz');
dotProp.get({foo: {bar: {baz: null}}}, 'foo.bar.baz');
dotProp.get({foo: {bar: 'a'}}, 'foo.fake');
dotProp.get({foo: {bar: 'a'}}, 'foo.fake.fake2');
dotProp.get({'\\': true}, '\\');
dotProp.get({'\\foo': true}, '\\foo');
dotProp.get({'bar\\': true}, 'bar\\');
dotProp.get({'foo\\bar': true}, 'foo\\bar');
dotProp.get({'\\.foo': true}, '\\\\.foo');
dotProp.get({'bar\\.': true}, 'bar\\\\.');
dotProp.get({'foo\\.bar': true}, 'foo\\\\.bar');

const fixture2 = {};
Object.defineProperty(fixture2, 'foo', {
value: 'bar',
enumerable: false
});
m.get(f2, 'foo');
m.get({}, 'hasOwnProperty');
dotProp.get(fixture2, 'foo');
dotProp.get({}, 'hasOwnProperty');

function fn() {}
fn.foo = {bar: 1};
m.get(fn);
m.get(fn, 'foo');
m.get(fn, 'foo.bar');
dotProp.get(fn);
dotProp.get(fn, 'foo');
dotProp.get(fn, 'foo.bar');

const f3 = {foo: null};
m.get(f3, 'foo.bar');
const fixture3 = {foo: null};
dotProp.get(fixture3, 'foo.bar');

m.get({'foo.baz': {bar: true}}, 'foo\\.baz.bar');
m.get({'fo.ob.az': {bar: true}}, 'fo\\.ob\\.az.bar');
dotProp.get({'foo.baz': {bar: true}}, 'foo\\.baz.bar');
dotProp.get({'fo.ob.az': {bar: true}}, 'fo\\.ob\\.az.bar');

m.get(null, 'foo.bar', false);
m.get('foo', 'foo.bar', false);
m.get([], 'foo.bar', false);
m.get(undefined, 'foo.bar', false);
dotProp.get(null, 'foo.bar', false);
dotProp.get('foo', 'foo.bar', false);
dotProp.get([], 'foo.bar', false);
dotProp.get(undefined, 'foo.bar', false);
})
.add('set', () => {
const func = () => 'test';
let f1 = {};
let fixture1 = {};

m.set(f1, 'foo', 2);
dotProp.set(fixture1, 'foo', 2);

f1 = {foo: {bar: 1}};
m.set(f1, 'foo.bar', 2);
fixture1 = {foo: {bar: 1}};
dotProp.set(fixture1, 'foo.bar', 2);

m.set(f1, 'foo.bar.baz', 3);
dotProp.set(fixture1, 'foo.bar.baz', 3);

m.set(f1, 'foo.bar', 'test');
dotProp.set(fixture1, 'foo.bar', 'test');

m.set(f1, 'foo.bar', null);
dotProp.set(fixture1, 'foo.bar', null);

m.set(f1, 'foo.bar', false);
dotProp.set(fixture1, 'foo.bar', false);

m.set(f1, 'foo.bar', undefined);
dotProp.set(fixture1, 'foo.bar', undefined);

m.set(f1, 'foo.fake.fake2', 'fake');
dotProp.set(fixture1, 'foo.fake.fake2', 'fake');

m.set(f1, 'foo.function', func);
dotProp.set(fixture1, 'foo.function', func);

function fn() {}
m.set(fn, 'foo.bar', 1);
dotProp.set(fn, 'foo.bar', 1);

f1.fn = fn;
m.set(f1, 'fn.bar.baz', 2);
fixture1.fn = fn;
dotProp.set(fixture1, 'fn.bar.baz', 2);

const f2 = {foo: null};
m.set(f2, 'foo.bar', 2);
const fixture2 = {foo: null};
dotProp.set(fixture2, 'foo.bar', 2);

const f3 = {};
m.set(f3, '', 3);
const fixture3 = {};
dotProp.set(fixture3, '', 3);

m.set(f1, 'foo\\.bar.baz', true);
dotProp.set(fixture1, 'foo\\.bar.baz', true);

m.set(f1, 'fo\\.ob\\.ar.baz', true);
dotProp.set(fixture1, 'fo\\.ob\\.ar.baz', true);
})
.add('delete', () => {
const func = () => 'test';
Expand All @@ -102,7 +102,7 @@ suite
func
};

const f1 = {
const fixture1 = {
foo: {
bar: {
baz: inner
Expand All @@ -113,49 +113,49 @@ suite
}
};

m.delete(f1, 'foo.bar.baz.c');
dotProp.delete(fixture1, 'foo.bar.baz.c');

m.delete(f1, 'top');
dotProp.delete(fixture1, 'top');

m.delete(f1, 'foo.bar.baz.func.foo');
dotProp.delete(fixture1, 'foo.bar.baz.func.foo');

m.delete(f1, 'foo.bar.baz.func');
dotProp.delete(fixture1, 'foo.bar.baz.func');

m.set(f1, 'foo\\.bar.baz', true);
m.delete(f1, 'foo\\.bar.baz');
dotProp.set(fixture1, 'foo\\.bar.baz', true);
dotProp.delete(fixture1, 'foo\\.bar.baz');

const f2 = {};
m.set(f2, 'foo.bar\\.baz', true);
m.delete(f2, 'foo.bar\\.baz');
const fixture2 = {};
dotProp.set(fixture2, 'foo.bar\\.baz', true);
dotProp.delete(fixture2, 'foo.bar\\.baz');

f2.dotted = {
fixture2.dotted = {
sub: {
'dotted.prop': 'foo',
other: 'prop'
}
};
m.delete(f2, 'dotted.sub.dotted\\.prop');
dotProp.delete(fixture2, 'dotted.sub.dotted\\.prop');
})
.add('has', () => {
const f1 = {foo: {bar: 1}};
m.has(f1);
m.has(f1, 'foo');
m.has({foo: 1}, 'foo');
m.has({foo: null}, 'foo');
m.has({foo: undefined}, 'foo');
m.has({foo: {bar: true}}, 'foo.bar');
m.has({foo: {bar: {baz: true}}}, 'foo.bar.baz');
m.has({foo: {bar: {baz: null}}}, 'foo.bar.baz');
m.has({foo: {bar: 'a'}}, 'foo.fake.fake2');
const fixture1 = {foo: {bar: 1}};
dotProp.has(fixture1);
dotProp.has(fixture1, 'foo');
dotProp.has({foo: 1}, 'foo');
dotProp.has({foo: null}, 'foo');
dotProp.has({foo: undefined}, 'foo');
dotProp.has({foo: {bar: true}}, 'foo.bar');
dotProp.has({foo: {bar: {baz: true}}}, 'foo.bar.baz');
dotProp.has({foo: {bar: {baz: null}}}, 'foo.bar.baz');
dotProp.has({foo: {bar: 'a'}}, 'foo.fake.fake2');

function fn() {}
fn.foo = {bar: 1};
m.has(fn);
m.has(fn, 'foo');
m.has(fn, 'foo.bar');
dotProp.has(fn);
dotProp.has(fn, 'foo');
dotProp.has(fn, 'foo.bar');

m.has({'foo.baz': {bar: true}}, 'foo\\.baz.bar');
m.has({'fo.ob.az': {bar: true}}, 'fo\\.ob\\.az.bar');
dotProp.has({'foo.baz': {bar: true}}, 'foo\\.baz.bar');
dotProp.has({'fo.ob.az': {bar: true}}, 'fo\\.ob\\.az.bar');
})
.on('cycle', event => {
console.log(String(event.target));
Expand Down
102 changes: 102 additions & 0 deletions index.d.ts
@@ -0,0 +1,102 @@
declare const dotProp: {
/**
@param obj - Object to get the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key.
Use `\\.` if you have a `.` in the key.
@param defaultValue - Default value.
@example
```
import dotProp = require('dot-prop');
dotProp.get({foo: {bar: 'unicorn'}}, 'foo.bar');
//=> 'unicorn'
dotProp.get({foo: {bar: 'a'}}, 'foo.notDefined.deep');
//=> undefined
dotProp.get({foo: {bar: 'a'}}, 'foo.notDefined.deep', 'default value');
//=> 'default value'
dotProp.get({foo: {'dot.dot': 'unicorn'}}, 'foo.dot\\.dot');
//=> 'unicorn'
```
*/
get<T = unknown>(
obj: {[key: string]: unknown},
path: string,
defaultValue?: T
): T;

/**
@param obj - Object to set the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key.
Use `\\.` if you have a `.` in the key.
@param value - Value to set at `path`.
@example
```
import dotProp = require('dot-prop');
const obj = {foo: {bar: 'a'}};
dotProp.set(obj, 'foo.bar', 'b');
console.log(obj);
//=> {foo: {bar: 'b'}}
const foo = dotProp.set({}, 'foo.bar', 'c');
console.log(foo);
//=> {foo: {bar: 'c'}}
dotProp.set(obj, 'foo.baz', 'x');
console.log(obj);
//=> {foo: {bar: 'b', baz: 'x'}}
```
*/
set<T extends {[key: string]: unknown}>(
obj: T,
path: string,
value: unknown
): T;

/**
@param obj - Object to test the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key.
Use `\\.` if you have a `.` in the key.
@example
```
import dotProp = require('dot-prop');
dotProp.has({foo: {bar: 'unicorn'}}, 'foo.bar');
//=> true
```
*/
has(obj: {[key: string]: unknown}, path: string): boolean;

/**
@param obj Object to delete the `path` value.
@param path - Path of the property in the object, using `.` to separate each nested key.
Use `\\.` if you have a `.` in the key.
@example
```
import dotProp = require('dot-prop');
const obj = {foo: {bar: 'a'}};
dotProp.delete(obj, 'foo.bar');
console.log(obj);
//=> {foo: {}}
obj.foo.bar = {x: 'y', y: 'x'};
dotProp.delete(obj, 'foo.bar.x');
console.log(obj);
//=> {foo: {bar: {y: 'x'}}}
```
*/
delete(obj: {[key: string]: unknown}, path: string): void;
};

export = dotProp;
18 changes: 18 additions & 0 deletions index.test-d.ts
@@ -0,0 +1,18 @@
import {expectType} from 'tsd';
import dotProp = require('.');

expectType<unknown>(dotProp.get({foo: {bar: 'unicorn'}}, 'foo.bar'));
expectType<unknown>(dotProp.get({foo: {bar: 'a'}}, 'foo.notDefined.deep'));
expectType<string>(
dotProp.get({foo: {bar: 'a'}}, 'foo.notDefined.deep', 'default value')
);
expectType<unknown>(
dotProp.get({foo: {'dot.dot': 'unicorn'}}, 'foo.dot\\.dot')
);

const obj = {foo: {bar: 'a'}};
expectType<typeof obj>(dotProp.set(obj, 'foo.bar', 'b'));

expectType<boolean>(dotProp.has({foo: {bar: 'unicorn'}}, 'foo.bar'));

expectType<void>(dotProp.delete({foo: {bar: 'a'}}, 'foo.bar'));
11 changes: 6 additions & 5 deletions package.json
Expand Up @@ -13,11 +13,12 @@
"node": ">=6"
},
"scripts": {
"test": "xo && ava",
"test": "xo && ava && tsd",
"bench": "node bench.js"
},
"files": [
"index.js"
"index.js",
"index.d.ts"
],
"keywords": [
"obj",
Expand All @@ -38,9 +39,9 @@
"is-obj": "^1.0.0"
},
"devDependencies": {
"ava": "*",
"ava": "^1.4.1",
"benchmark": "^2.1.4",
"microtime": "^2.1.8",
"xo": "*"
"tsd": "^0.7.2",
"xo": "^0.24.0"
}
}