8

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?

2 Answers 2

18

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.

Sign up to request clarification or add additional context in comments.

1 Comment

There's another cool way of typing objects in TypeScript, by the way: const myObj: Record<string, number | RegExp> = {...};
0

Option 1

  1. Cast to any
  2. Cast to keyof typeof

Example:

const options = { '-a': 'Alpha', '-o': 'Omega' }
let strOptions = 'Options are:'

for (const k in options) {
  const kAny: any = k
  const key: (keyof typeof options) = kAny

  strOptions += `\n${ key } => ${ options[ key ] }`
}

Option 2:

  1. Use a map
const options = new Map([
  ['-a', 'Alpha'],
  ['-o', 'Omega'],
])

let strOptions = 'Options are:'

options.forEach((v, k) => {
  strOptions += `\n${ k } => ${ v }`
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.