I'v faced a problem trying to define an interface for the following structure:
interface JSONRecord {
[propName: string]: any;
}
type ReturnType = (id: string|number, field: string, record: JSONRecord) => string
export const formatDictionary = ({
mode = "render", key = "originalValue",
defaultKey = "originalValue"
}):ReturnType => (id, field, record) => {
...
}
interface Lookup {
Dictionary: ({mode, key, defaultKey}:{mode: string, key: string, defaultKey: string}) => ReturnType,
...
}
export const functionLookup:Lookup = {
Dictionary: formatDictionary,
...
}
export const formatField = (params:JSONRecord):string|ReturnType => {
const type:string = params.type
if (type === undefined) { return identity }
const fn = functionLookup[type]
if (fn === undefined) { return identity }
return fn({ ...params })
}
I'm getting the following errors:
const fn = functionLookup[type]
: Element implicitly has an 'any' type becasue expression of type string can't be used to index type 'Lookup'. No index signature with parameter of type 'string' was found on type 'Lookup'.[x: string]: ({mode, key, defaultKey}:{mode: string, key: string, defaultKey: string}) => ReturnType
the error disappears, but i want to be specific with the arguments that can be passed.return fn({ ...params })
: Expected 3 arguments, but got 1{mode, key, defaultKey}
or is it expecting the ReturnType function there?I would appreciate any help. Thanks a lot in advance :)
In you case (from sandbox):
const anExampleVariable = "Hello World"
console.log(anExampleVariable)
// To learn more about the language, click above in "Examples" or "What's New".
// Otherwise, get started by removing these comments and the world is your playground.
interface Lookup {
test: number
}
const functionLookup:Lookup = {
test: 5
}
const params = {
type: 'test'
};
const type = params.type
const a = functionLookup[type]
params
variable is infered as {type: string}
.
Here functionLookup[type]
you want use type
as index for functionLookup
, but TS does not work that way. Because you can't just use general type string
as index for Lookup
type.
Lookup
allows you to use only literal test
as index.
So you can add as const
prefix to your params
vvariable.
const params = {
type: 'test'
} as const;
You can make Lookup indexed:
interface Lookup {
test: number,
[prop:string]:number
}
Or, you can explicitly define a Record type for params
:
const params:Record<string, keyof Lookup> = {
type: 'test'
}