adplus-dvertising

No index signature with a parameter of type 'string' was found on type '

Asked 3 years ago
Viewed 3.85 k times

I was working on my first firebase typescript function project

I have following code snippet.

const files = {
    status: './src/api/status.f.js',
    invite: './src/api/invite.f.js',
    user: './src/api/user.f.js',
    auth: './src/api/auth.f.js',
    social: './src/api/social.f.js'
}

for (let file in files)
    if (files.hasOwnProperty(file)) {
        // Setting function name equivalent to the file name
        if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === file) {
            const ApiClass = require(files[file])
            const app = new ApiClass(context)
            exports[file] = app.handler
        }
    }

In this, at this line i am getting following error const ApiClass = require(files[file])

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ status: string; invite: string; user: string; auth: string; social: string; }'. No index signature with a parameter of type 'string' was found on type '{ status: string; invite: string; user: string; auth: string; social: string; }'

Primary Question: Can someone help me figure out what I am doing wrong here?

asked 3 years ago

Correct Answer

The type error is shown because you turned on "noImplicitAny": true in tsconfig.

If you like to keep "noImplicitAny": true, then there're 2 fixes to your problem, choose either one.

  1. const ApiClass = require(files[file as keyof typeof files])
  2. const files: { [key: string]: string } = { ... }

After some digging, I think the optimal way is to augment the Object.prototype.hasOwnProperty() method's signature.

// somewhere in your project, write:

interface Object {
  hasOwnProperty<T>(this: T, v: any): v is keyof T
}

This way .hasOwnProperty acts as a type guard that narrows down type of file to be keyof typeof files automatically.

answered 3 years ago