0

Could anyone explain why do I get the following error?

Property 'prop1' does not exist on type 'A'.ts(2339)

The code

interface A {
  prop1:string;
};

class myClass<A> {
  ptop1: string;
  constructor(input: A) {
    this.ptop1 = input.prop1;  //error happens in this line (Property 'prop1' does not exist on type 'A'.ts(2339))
  }
}
nash11
  • 8,220
  • 3
  • 19
  • 55
Sami
  • 17
  • 8

3 Answers3

1

There is a conflict between <A> and type interface A. The code in this line myClass <A> confuses the myClass class, so theconstructor (input: A)statement refers A to A inside the<A>, not interface A. Why don't you just use code like this ?

class myClass{
  ptop1:string;
  constructor(input:A){
    this.ptop1=input.prop1;
  }
}
Wuriyanto
  • 362
  • 3
  • 6
  • Thanks. Because I had seen in react in order to pass the props and state properties, people use this technique. So I wonder why this method works there – Sami Oct 10 '20 at 11:33
1

In your class, the <A> indicates a generic; so, inside the class, A refers to the generic type, ignoring any specific type or interface that you might have this symbol declared previously.

A generic type represents any type, thus you can only use the generic parameter as if it could be of any and all types, and as such you cannot access any specific propertie.

That said, in your case you should use a more specific T type using the implements keyword to tell the compiler the generic type T is something that implements the A interface.


interface A {
  p1: string
}

/* THIS DOES NOT WORK */
class c <T implements A> {
  t1: string;
  constructor(t: T){
    this.t1 = t.p1
  }
}

unfortunately, typescript does not allow the T implements A expression in a generic declaration; however, there is a workaround, less expressive, by abusing the extends keyword

interface A {
  p1: string
}

class c <T extends A> {
  t1: string;
  constructor(t: T){
    this.t1 = t.p1
  }
}
PA.
  • 28,486
  • 9
  • 71
  • 95
  • 1
    What do you mean by "less expressive"? It seems to two keywords are interchangeable wrt type definitions. – Bergi Oct 10 '20 at 16:21
  • nope, a class "implements" an interface; and "extends" another class. – PA. Oct 10 '20 at 16:30
  • 1
    Yes, that's on a `class` definition, but the `T` generic type is not a class. – Bergi Oct 10 '20 at 16:32
  • the generic is any type, including a class. And in this case T is acting as a class, for "extends" to have meaning. – PA. Oct 10 '20 at 17:22
  • 1
    @Bergi @PA. Replying to _And in this case T is acting as a class, for "extends" to have meaning._ , in typescript any type and can extend any other type not necessarily class. Following this `'a' extends 'a' | 'b'` is valid and none of them are (act as) class. So in the question, `A` could be any other type not only a class or interface. Moreover, `T` could be an interface and interfaces can extend other interfaces or even a type, check [here](https://www.typescriptlang.org/docs/handbook/interfaces.html#extending-interfaces) and [here](https://stackoverflow.com/a/41385149/11642727) – Shivam Singla Oct 11 '20 at 14:02
0

You can do like this

interface A {
  prop1: string
}

// constraint A1 with A
class myClass <A1 extends A> {
  ptop1: string
  constructor(input: A1){
    this.ptop1 = input.prop1
  }
}

Playground

Shivam Singla
  • 2,117
  • 1
  • 10
  • 22