1
export interface DemoAttr<T> {
    attr: Demo<T>
    a: boolean
    b: string
}

export class Demo<T> implements DemoAttr<T>{
    attr = {} as Demo<T>
    a = false
    b = ''
    
    setAttr(key: keyof DemoAttr<T>, value: DemoAttr<T>[keyof DemoAttr<T>]) {
        // how to fix it? and why?
        // I use `any` to replace the value type is not work either
        this.attr[key] = value
    }

}

I just wonder to know what reason causes this error, any why even use any can not fix it either?

and if I remove the b attribute and use any as value type then it works well.

1 Answer 1

1

In order to fix it, you need to use type inference on function arguments:

export interface DemoAttr<T> {
  attr: Demo<T>
  a: boolean
  b: string
}

export class Demo<T> implements DemoAttr<T>{
  attr = new Demo<T>()
  a = false
  b = ''

  setAttr<Key extends keyof Demo<T>>(key: Key, value: Demo<T>[Key]) {
    this.attr[key] = value
  }
}

Playground

More about this topic you van find in my blog.

As you might have noticed, I have provided generic Key and applied a constraint Key extends keyof Demo<T>. It means that Key should be a subtype of Demo<T> keys/props. But you probably aware of that, because you were close. However, using

setAttr(key: keyof DemoAttr<T>, value: DemoAttr<T>[keyof DemoAttr<T>])

without generic parameter is not safe, because there is no correlation between key and value. In other words, key might be an a prop and value might be a string. Both of them are valid but in the same moment it is not type safe.

You also have used DemoAttr<T> as a dependent type for arguments, which is not correct because attr is in fact a Demo type and not DemoAttr. attr is a Demo instance, hence you can't use DemoAttr interface for that purpose

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.