From c52608e5b4dcfaefadfb961cc089dccf7fedf837 Mon Sep 17 00:00:00 2001 From: Christian Ruigrok Date: Thu, 10 Jan 2019 20:25:41 +0100 Subject: [PATCH 1/4] Update match-sorter to 2.3 and fix issues with keys --- types/match-sorter/index.d.ts | 26 +-- types/match-sorter/match-sorter-tests.ts | 208 +++++++++++++---------- 2 files changed, 131 insertions(+), 103 deletions(-) diff --git a/types/match-sorter/index.d.ts b/types/match-sorter/index.d.ts index e1a7e8efe4..9d48e0b880 100644 --- a/types/match-sorter/index.d.ts +++ b/types/match-sorter/index.d.ts @@ -1,6 +1,7 @@ -// Type definitions for match-sorter 2.2 +// Type definitions for match-sorter 2.3 // Project: https://github.com/kentcdodds/match-sorter#readme // Definitions by: Claas Ahlrichs +// Christian Ruigrok // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped declare namespace matchSorter { @@ -18,24 +19,15 @@ declare namespace matchSorter { } } -interface MinRanking { - minRanking: number; - key: string; -} - -interface MaxRanking { - maxRanking: number; - key: string; -} - -interface MinMaxRanking { - minRanking: number; - maxRanking: number; - key: string; +interface ExtendedKeyOptions { + minRanking?: number; + maxRanking?: number; + treshold?: number; + key: string | ((item: T) => string); } interface Options { - keys?: Array<(string | ((item: T) => string) | MinRanking | MaxRanking | MinMaxRanking)>; + keys?: Array string) | ExtendedKeyOptions>; threshold?: number; keepDiacritics?: boolean; } @@ -47,6 +39,6 @@ interface Options { * @param options - Some options to configure the sorter * @return the new sorted array */ -declare function matchSorter(items: T[], value: string, options?: Options): T[]; +declare function matchSorter(items: ReadonlyArray, value: string, options?: Options): T[]; export = matchSorter; diff --git a/types/match-sorter/match-sorter-tests.ts b/types/match-sorter/match-sorter-tests.ts index e1496cba9f..a6529f7998 100644 --- a/types/match-sorter/match-sorter-tests.ts +++ b/types/match-sorter/match-sorter-tests.ts @@ -2,129 +2,165 @@ import matchSorter = require('match-sorter'); // # Basic Sample { - const list = ['hi', 'hey', 'hello', 'sup', 'yo']; - matchSorter(list, 'h'); // ['hi', 'hey', 'hello'] - matchSorter(list, 'y'); // ['yo', 'hey'] - matchSorter(list, 'z'); // [] + const list = ['hi', 'hey', 'hello', 'sup', 'yo']; + matchSorter(list, 'h'); // ['hi', 'hey', 'hello'] + matchSorter(list, 'y'); // ['yo', 'hey'] + matchSorter(list, 'z'); // [] } // # Advanced options // ## keys: [string] { - const objList = [ - {name: 'Janice', color: 'Green'}, - {name: 'Fred', color: 'Orange'}, - {name: 'George', color: 'Blue'}, - {name: 'Jen', color: 'Red'}, - ]; - matchSorter(objList, 'g', {keys: ['name', 'color']}); - // [{name: 'George', color: 'Blue'}, {name: 'Janice', color: 'Green'}, {name: 'Fred', color: 'Orange'}] + const objList = [ + { name: 'Janice', color: 'Green' }, + { name: 'Fred', color: 'Orange' }, + { name: 'George', color: 'Blue' }, + { name: 'Jen', color: 'Red' } + ]; + matchSorter(objList, 'g', { keys: ['name', 'color'] }); + // [{name: 'George', color: 'Blue'}, {name: 'Janice', color: 'Green'}, {name: 'Fred', color: 'Orange'}] - matchSorter(objList, 're', {keys: ['color', 'name']}); - // [{name: 'Jen', color: 'Red'}, {name: 'Janice', color: 'Green'}, {name: 'Fred', color: 'Orange'}, {name: 'George', color: 'Blue'}] + matchSorter(objList, 're', { keys: ['color', 'name'] }); + // [{name: 'Jen', color: 'Red'}, {name: 'Janice', color: 'Green'}, {name: 'Fred', color: 'Orange'}, {name: 'George', color: 'Blue'}] } // ### Array of values { - const iceCreamYum = [ - {favoriteIceCream: ['mint', 'chocolate']}, - {favoriteIceCream: ['candy cane', 'brownie']}, - {favoriteIceCream: ['birthday cake', 'rocky road', 'strawberry']}, - ]; - matchSorter(iceCreamYum, 'cc', {keys: ['favoriteIceCream']}); - // [{favoriteIceCream: ['candy cane', 'brownie']}, {favoriteIceCream: ['mint', 'chocolate']}] + const iceCreamYum = [ + { favoriteIceCream: ['mint', 'chocolate'] }, + { favoriteIceCream: ['candy cane', 'brownie'] }, + { favoriteIceCream: ['birthday cake', 'rocky road', 'strawberry'] } + ]; + matchSorter(iceCreamYum, 'cc', { keys: ['favoriteIceCream'] }); + // [{favoriteIceCream: ['candy cane', 'brownie']}, {favoriteIceCream: ['mint', 'chocolate']}] } // ### Nested Keys { - const nestedObjList = [ - {name: {first: 'Janice'}}, - {name: {first: 'Fred'}}, - {name: {first: 'George'}}, - {name: {first: 'Jen'}}, - ]; - matchSorter(nestedObjList, 'j', {keys: ['name.first']}); - // [{name: {first: 'Janice'}}, {name: {first: 'Jen'}}] + const nestedObjList = [ + { name: { first: 'Janice' } }, + { name: { first: 'Fred' } }, + { name: { first: 'George' } }, + { name: { first: 'Jen' } } + ]; + matchSorter(nestedObjList, 'j', { keys: ['name.first'] }); + // [{name: {first: 'Janice'}}, {name: {first: 'Jen'}}] } { - const nestedObjList = [ - {name: [{first: 'Janice'}]}, - {name: [{first: 'Fred'}]}, - {name: [{first: 'George'}]}, - {name: [{first: 'Jen'}]}, - ]; - matchSorter(nestedObjList, 'j', {keys: ['name.0.first']}); - // [{name: {first: 'Janice'}}, {name: {first: 'Jen'}}] - // matchSorter(nestedObjList, 'j', {keys: ['name[0].first']}) does not work + const nestedObjList = [ + { name: [{ first: 'Janice' }] }, + { name: [{ first: 'Fred' }] }, + { name: [{ first: 'George' }] }, + { name: [{ first: 'Jen' }] } + ]; + matchSorter(nestedObjList, 'j', { keys: ['name.0.first'] }); + // [{name: {first: 'Janice'}}, {name: {first: 'Jen'}}] + // matchSorter(nestedObjList, 'j', {keys: ['name[0].first']}) does not work } // ### Property Callbacks { - const list = [{name: 'Janice'}, {name: 'Fred'}, {name: 'George'}, {name: 'Jen'}]; - matchSorter(list, 'j', {keys: [item => item.name]}); - // [{name: 'Janice'}, {name: 'Jen'}] + const list = [ + { name: 'Janice' }, + { name: 'Fred' }, + { name: 'George' }, + { name: 'Jen' } + ]; + matchSorter(list, 'j', { keys: [item => item.name] }); + // [{name: 'Janice'}, {name: 'Jen'}] } // ### Min and Max Ranking { - const tea = [ - {tea: 'Earl Grey', alias: 'A'}, - {tea: 'Assam', alias: 'B'}, - {tea: 'Black', alias: 'C'}, - ]; - matchSorter(tea, 'A', { - keys: ['tea', {maxRanking: matchSorter.rankings.STARTS_WITH, key: 'alias'}], - }); - // without maxRanking, Earl Grey would come first because the alias "A" would be CASE_SENSITIVE_EQUAL - // `tea` key comes before `alias` key, so Assam comes first even though both match as STARTS_WITH - // [{tea: 'Assam', alias: 'B'}, {tea: 'Earl Grey', alias: 'A'},{tea: 'Black', alias: 'C'}] + const tea = [ + { tea: 'Earl Grey', alias: 'A' }, + { tea: 'Assam', alias: 'B' }, + { tea: 'Black', alias: 'C' } + ]; + matchSorter(tea, 'A', { + keys: [ + 'tea', + { maxRanking: matchSorter.rankings.STARTS_WITH, key: 'alias' } + ] + }); + // without maxRanking, Earl Grey would come first because the alias "A" would be CASE_SENSITIVE_EQUAL + // `tea` key comes before `alias` key, so Assam comes first even though both match as STARTS_WITH + // [{tea: 'Assam', alias: 'B'}, {tea: 'Earl Grey', alias: 'A'},{tea: 'Black', alias: 'C'}] } { - const tea = [ - {tea: 'Milk', alias: 'moo'}, - {tea: 'Oolong', alias: 'B'}, - {tea: 'Green', alias: 'C'}, - ]; - matchSorter(tea, 'oo', { - keys: ['tea', {minRanking: matchSorter.rankings.EQUAL, key: 'alias'}], - }); - // minRanking bumps Milk up to EQUAL from CONTAINS (alias) - // Oolong matches as STARTS_WITH - // Green is missing due to no match - // [{tea: 'Milk', alias: 'moo'}, {tea: 'Oolong', alias: 'B'}] + const tea = [ + { tea: 'Milk', alias: 'moo' }, + { tea: 'Oolong', alias: 'B' }, + { tea: 'Green', alias: 'C' } + ]; + matchSorter(tea, 'oo', { + keys: ['tea', { minRanking: matchSorter.rankings.EQUAL, key: 'alias' }] + }); + // minRanking bumps Milk up to EQUAL from CONTAINS (alias) + // Oolong matches as STARTS_WITH + // Green is missing due to no match + // [{tea: 'Milk', alias: 'moo'}, {tea: 'Oolong', alias: 'B'}] +} + +// # key: methods +{ + const tea = [ + { tea: 'Milk', alias: 'moo' }, + { tea: 'Oolong', alias: 'B' }, + { tea: 'Green', alias: 'C' } + ]; + matchSorter(tea, 'oo', { + keys: [ + item => item.tea, + { minRanking: matchSorter.rankings.EQUAL, key: item => item.alias } + ] + }); + // minRanking bumps Milk up to EQUAL from CONTAINS (alias) + // Oolong matches as STARTS_WITH + // Green is missing due to no match + // [{tea: 'Milk', alias: 'moo'}, {tea: 'Oolong', alias: 'B'}] } // ## threshold: number { - const fruit = ['orange', 'apple', 'grape', 'banana']; - matchSorter(fruit, 'ap', {threshold: matchSorter.rankings.NO_MATCH}); - // ['apple', 'grape', 'orange', 'banana'] (returns all items, just sorted by best match) + const fruit = ['orange', 'apple', 'grape', 'banana']; + matchSorter(fruit, 'ap', { threshold: matchSorter.rankings.NO_MATCH }); + // ['apple', 'grape', 'orange', 'banana'] (returns all items, just sorted by best match) - const things = ['google', 'airbnb', 'apple', 'apply', 'app']; - matchSorter(things, 'app', {threshold: matchSorter.rankings.EQUAL}); - // ['app'] (only items that are equal) + const things = ['google', 'airbnb', 'apple', 'apply', 'app']; + matchSorter(things, 'app', { threshold: matchSorter.rankings.EQUAL }); + // ['app'] (only items that are equal) - const otherThings = ['fiji apple', 'google', 'app', 'crabapple', 'apple', 'apply']; - matchSorter(otherThings, 'app', {threshold: matchSorter.rankings.WORD_STARTS_WITH}); - // ['app', 'apple', 'apply', 'fiji apple'] (everything that matches with "word starts with" or better) + const otherThings = [ + 'fiji apple', + 'google', + 'app', + 'crabapple', + 'apple', + 'apply' + ]; + matchSorter(otherThings, 'app', { + threshold: matchSorter.rankings.WORD_STARTS_WITH + }); + // ['app', 'apple', 'apply', 'fiji apple'] (everything that matches with "word starts with" or better) } // ## keepDiacritics: boolean { - const thingsWithDiacritics = [ - 'jalapeño', - 'à la carte', - 'café', - 'papier-mâché', - 'à la mode', - ]; - matchSorter(thingsWithDiacritics, 'aa'); - // ['jalapeño', 'à la carte', 'à la mode', 'papier-mâché'] + const thingsWithDiacritics = [ + 'jalapeño', + 'à la carte', + 'café', + 'papier-mâché', + 'à la mode' + ]; + matchSorter(thingsWithDiacritics, 'aa'); + // ['jalapeño', 'à la carte', 'à la mode', 'papier-mâché'] - matchSorter(thingsWithDiacritics, 'aa', {keepDiacritics: true}); - // ['jalapeño', 'à la carte'] + matchSorter(thingsWithDiacritics, 'aa', { keepDiacritics: true }); + // ['jalapeño', 'à la carte'] - matchSorter(thingsWithDiacritics, 'à', {keepDiacritics: true}); - // ['à la carte', 'à la mode'] + matchSorter(thingsWithDiacritics, 'à', { keepDiacritics: true }); + // ['à la carte', 'à la mode'] } From 046bf588e2d62b80635bd5eca2453f84e0c83ff9 Mon Sep 17 00:00:00 2001 From: Christian Ruigrok Date: Wed, 16 Jan 2019 20:55:51 +0100 Subject: [PATCH 2/4] Fix typo and make ExtendedKeyOptions more restrictive --- types/match-sorter/index.d.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/types/match-sorter/index.d.ts b/types/match-sorter/index.d.ts index 9d48e0b880..1df513584c 100644 --- a/types/match-sorter/index.d.ts +++ b/types/match-sorter/index.d.ts @@ -19,12 +19,10 @@ declare namespace matchSorter { } } -interface ExtendedKeyOptions { - minRanking?: number; - maxRanking?: number; - treshold?: number; - key: string | ((item: T) => string); -} +type ExtendedKeyOptions = { key: string | ((item: T) => string) } & ( + | { minRanking: number; threshold?: number } + | { maxRanking: number; threshold?: number } + | { threshold: number }); interface Options { keys?: Array string) | ExtendedKeyOptions>; @@ -39,6 +37,10 @@ interface Options { * @param options - Some options to configure the sorter * @return the new sorted array */ -declare function matchSorter(items: ReadonlyArray, value: string, options?: Options): T[]; +declare function matchSorter( + items: ReadonlyArray, + value: string, + options?: Options +): T[]; export = matchSorter; From 759dd92469a9a5456979bccecf9eb1bf25a47609 Mon Sep 17 00:00:00 2001 From: Christian Ruigrok Date: Wed, 16 Jan 2019 21:03:00 +0100 Subject: [PATCH 3/4] Undo unnecessary threshold keys --- types/match-sorter/index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/match-sorter/index.d.ts b/types/match-sorter/index.d.ts index 1df513584c..fbb92c9909 100644 --- a/types/match-sorter/index.d.ts +++ b/types/match-sorter/index.d.ts @@ -20,8 +20,8 @@ declare namespace matchSorter { } type ExtendedKeyOptions = { key: string | ((item: T) => string) } & ( - | { minRanking: number; threshold?: number } - | { maxRanking: number; threshold?: number } + | { minRanking: number } + | { maxRanking: number } | { threshold: number }); interface Options { From 7f86bbd856d0d5dbd84b0cb96dc5bdda3fb9a5a4 Mon Sep 17 00:00:00 2001 From: Claas Ahlrichs Date: Thu, 17 Jan 2019 18:58:56 +0100 Subject: [PATCH 4/4] Fix typescript version for match-sorter definitions Co-Authored-By: ChrisRu --- types/match-sorter/index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/match-sorter/index.d.ts b/types/match-sorter/index.d.ts index fbb92c9909..dd4f5bc5a7 100644 --- a/types/match-sorter/index.d.ts +++ b/types/match-sorter/index.d.ts @@ -3,6 +3,7 @@ // Definitions by: Claas Ahlrichs // Christian Ruigrok // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.1 declare namespace matchSorter { namespace rankings {