node.js - Dette uttrykket kan ikke kalles. Type 'string' har ingen kallsignaturer
Jeg prøver å lage en malfil fra et objekt der nøkkelen kan være enten en streng eller en funksjon som returnerer en streng:
export const createDynamicTemplate = (
templateParams: CreateDynamicTemplateParams
) => {
const { template, projectPath = '', param = '' } = templateParams
const updatedTemplateArr = Object.keys(template).map((key: string) => {
return {
[key]: {
filePath: `${projectPath}/${key}`,
template: typeof template[key] === 'function' ?
template[key](param) : template[key],
},
}
})
const updatedTemplate = Object.assign({}, ...updatedTemplateArr)
return updatedTemplate
}
Mine grensesnitt er:
export interface TemplateObject {
[key: string]: string
}
export interface FunctionalTemplateObject {
[key: string]: (param: string) => void
}
export interface CreateDynamicTemplateParams {
template: FunctionalTemplateObject | TemplateObject
projectPath: string
param: string
}
Det fortsetter å gi denne feilen i createDynamicTemplate selv om:
Dette uttrykket kan ikke kalles. Ikke alle komponenter av typen 'string | ((param: string) => void)' kan kalles. Typen 'string' har ingen kallbare signaturer.
Hva gjør jeg galt her?
Svar #1
Å sjekke typen til en barneegenskap til en variabel som refererer til et objekt vil ikke begrense typen til variabelobjektet. Du kan lagre verdien ved nøkkelen i en separat variabel først, og deretter sjekke den verdien for å begrense typen:
const updatedTemplateArr = Object.keys(template).map((key: string) => {
const item = template[key];
if (typeof item === 'function') {
return {
[key]: {
filePath: `${projectPath}/${key}`,
template: item(param),
},
}
}
})
Eller, enda bedre, bruk Object.entries for å få nøkkelen og verdien samtidig. (Merk også at det ikke er nødvendig å angi typen til .map-parametrene - TS kan utlede det automatisk helt fint)
const updatedTemplateArr = Object.entries(template).map(([key, value]) => {
if (typeof value === 'function') {
return {
[key]: {
filePath: `${projectPath}/${key}`,
template: value(param),
},
}
}
})
