Solution 1: Use type
instead of interface
That is because the type [key: string]: string
is not compatible with your Query
interface, the latter of which contains two allowed keys: lorem
and ipsum
, while the former contains any arbitrary string as key. This is an issue with TypeScript interfaces in general: a specific interface cannot be saved into a more generic interface.
However, a specific type can be saved into a more generic type, so a quick solution will be to simply convert your interface to types:
type Query = {
lorem: "0" | "1"
ipsum: string
}
const query: Query = {
lorem: "0",
ipsum: "Hello world"
}
type Input = {
[key: string]: string
}
const test = (input: Input) => {
return input["lorem"]
}
test(query)
Solution 2: Spread the variable when calling test()
An alternative solution will simply to keep the interfaces, but use ES6 object spread to deconstruct/spread the variable query
before passing it into test()
. By doing that, you will force TypeScript to recognize { ...query }
as indexable.
This solution is smart but a bit hack-ish, because you have to probably add a comment in the code to explain why you can't just use test(query)
instead of test({ ...query })
:
interface Query {
lorem: "0" | "1"
ipsum: string
}
const query: Query = {
lorem: "0",
ipsum: "Hello world"
}
interface Input {
[key: string]: string
}
const test = (input: Input) => {
return input["lorem"]
}
test({ ...query })
There is an extended thread on discussion on TypeScript's GitHub repo: might be a good place to read a little more about it.