0

I have this code:

class Label{
  constructor(
    public name:string='name',
    public configPath:string='path',
    public foo:{bar:string} = {bar:'hello'}
  ){

  }
}

const labelName:string = 'bob'
const configPath:string = './path/to/a/config.file'
const label_name = new Label(labelName, configPath);

function line(line: string):void {
  const regex = /\./g;
  let path = line.split(regex);
  let startingObj = label_name;
  function addPath(path: string) {
    startingObj = startingObj[path];
  }
  path.forEach(addPath);
  console.log(startingObj);
}

line('name')
line('foo.bar')

line is an input that I want to use to log elements via a terminal request. I imagine it is pretty dangerous way to access the members of a class, it is something that I plan to use during development. line should have this format: report.q1, an I should be able to log the values in the console.

Ts is complaining about startingObj = startingObj[path]; with this error

Element implicitly has an 'any' type because expression of type 'string' >can't be used to index type 'Label'. No index signature with a parameter of >type 'string' was found on type 'App'.ts(7053)

I created a playground to explain what I am trying to do =).

What can I do to get rid of this error?

11
  • Please provide a self-contained minimal reproducible example that clearly demonstrates the issue you are facing, as plain text in the body of your post. Ideally I could paste such code into a standalone IDE and immediately get to work solving the problem without first needing to re-create it. So there should be no pseudocode, typos, unrelated errors, or undeclared types or values. (If you want to provide a playground link that's great, but please also put the full example in the body of the post as text.) Commented Jun 20, 2022 at 18:31
  • You are right I will provide that .. Commented Jun 20, 2022 at 19:00
  • shall I edit my original message? I think I will do that! Commented Jun 20, 2022 at 19:09
  • I know my first comment was a wall of text, but the operative part of it is that the minimal reproducible example should be plain text in the body of your post. Commented Jun 20, 2022 at 19:42
  • What you're doing isn't something the TypeScript compiler can verify as type safe. Your startingObject starts as a Label but then becomes other types, and TS doesn't model or track mutation like this. Splitting strings by dots also won't result in strongly typed string literals. If you just want to suppress the error and move on, you can annotate startingObject as the any type to stop the compiler from caring much about what you do with it, like this. Normally I wouldn't recommend using any, but in this case I don't think there's much better. Commented Jun 20, 2022 at 19:52

1 Answer 1

0

Looking further into Typescript documentations I realized why it is giving that problem, and I found a solution by doing (here a playground with the solution I found):

class Label {
  constructor(
    public name: string = 'name',
    public configPath: string = 'path',
    public foo: { bar: string } = { bar: 'hello' }
  ) {
  }
}

const labelName: string = 'bob'
const configPath: string = './path/to/a/config.file'
const label_name = new Label(labelName, configPath);

function line(line: string): void {
  const regex = /\./g;
  let path = (line.split(regex)as unknown)as KeysOfStartingObj[];
  let startingObj = (label_name as unknown)as Object;

  type KeysOfStartingObj = keyof typeof startingObj
  function addPath(path: KeysOfStartingObj) {
    startingObj = startingObj[path];
  }
  path.forEach(addPath);
  console.log(startingObj);
}

line('name')
line('foo.bar')

So basically TS was complaining because it didn't know much about the startingObj keys. So by doing type KeysOfStartingObj = keyof typeof startingObj I am creating a type which is the union of the keys in startingObj, then with let path = (line.split(regex)as unknown)as KeysOfStartingObj[]; I tell TS that the splitted string array is an array of KeysOfStartingObj. In the function signature as well I am telling TS that the arg path will be of the same type. So TS stops yelling at me =) 😇.

I will work on the function a little better cause at the moment it assumes that anything inside the path array is a key of startingObj, which is not true, as I could pass in some values which are not part of the object. But that was not the scope of my question. I just wanted to find a way to have TS stop giving that error. I have same errore in other places of my code and I now know how yo solve it! I hope this can be helpful to others!

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

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.