4

I have this error message when using Typescript with Fuse.js

TS2345: Argument of type '{ keys: string; }' is not assignable to parameter of type 'FuseOptions<{ 'ISBN': string; 'title': string; 'author': string; }>'. Types of property 'keys' are incompatible. Type 'string' is not assignable to type '("title" | "ISBN" | "author")[] | { name: "title" | "ISBN" | "author"; weight: number; }[]'.

Here is the code:

let books = [{
        'ISBN': 'A',
        'title': "Old Man's War",
        'author': 'John Scalzi'
    },
    {
        'ISBN': 'B',
        'title': 'The Lock Artist',
        'author': 'Steve Hamilton'
    }
]

let options = {
    keys: 'title'
}
let fuse = new Fuse(books, options)

let filterResult = fuse.search('old')

The error is when hovering over options in let fuse = new Fuse(books, options)

krisk
  • 6,957
  • 1
  • 18
  • 30
R.Dixon
  • 107
  • 2
  • 11

2 Answers2

6

This just tripped me up for a bit too.

The compiler moves in order from top to bottom, so by the time it's looked at options, it's inferred it's a string[], which isn't compatible with the keyof of your book type. So add a type annotation to your declaration of options.

Also, the keys should be an array of keys.

Final result:

type Book = { ISBN:string; title: string; author: string; };

let options: Fuse.FuseOptions<Book>  = {
    keys: ['title'],
};
Daniel Hines
  • 63
  • 1
  • 4
0

It's probably a better idea to provide your type to your Fuse instance through a generic parameter with its constructor.

So in this case, something like this would properly type all Fuse configuration and methods, not just your options object:

type Book = { ISBN: string; title: string; author: string; };

const fuse = new Fuse<Book>(books, { keys: ['title'] });

// filterResult is of type Fuse.FuseResult<Book>[]
const filterResult = fuse.search('old');

// or, if you want result of type Book[] 
const books = filterResult.map(({ item }) => item);
heez
  • 2,029
  • 3
  • 27
  • 39