0

I'm learning Generics in Typescript and have one problem with implementation generic interface.

My interface

export interface ToTable<T> {
    value: T
    toColumns(): Column
    fromColumn<T>():T
}

I want to class which implements this interface have this field and methods which works with Column class.

export class Column {
    field: string = ''
    value: string = ''
}

and when I try to implement interface in User class

export class UserService implements ToTable<User> {
    value: User

    constructor() {
        this.value = new User()
    }
    fromColumn<User>(columns: Column[]): User {
        return this.value
    }

    toColumns(): Column {
        let col = new Column()
        col.field = 'name'
        col.value = 'testVal'
        return col
    }

}

in method "fromColumn" that should return User class object, I got error:

Type 'import("c:/Projects/Train-Projects/Test-directives/src/app/servisec/user").User' is not assignable to type 'User'.
  'User' could be instantiated with an arbitrary type which could be unrelated to 'import("c:/Projects/Train-Projects/Test-directives/src/app/servisec/user").User'.ts(2322)

User type in fromColumn method is not same with User class?

Georgy
  • 1,879
  • 2
  • 9
  • 14
irek
  • 1
  • 1
  • 1
    Do you have more than one `User` type in your project? – tromgy Nov 29 '21 at 17:58
  • Not yet, but in future want to add new Types which will be implement this method. I do it for have capability to convert all types to Column class, example: have Tool type { group: string, name: string, url: string } convert to Array of Column [ {field: 'group', value: 'test- group'}, {field: 'name', value: 'test- name'}, {field: url, value: 'test- url'} ] – irek Nov 29 '21 at 18:10

1 Answers1

2

Since you are defining your generic parameters in the interface definition, you don't need to declare it in your fromColumn function as well. You can just reuse it.

As for your error, it seams to be fixed when you remove the generic parmeter from your function declaration. It might be caused by the fact that you do not import the same User object in both files.

interface ToTable<T> {
    fromColumn():T
    /** ... **/
}

class UserService implements ToTable<User> {
    value: User

    constructor() {
        this.value = new User()
    }

    fromColumn(columns: Column[]): User {
        return this.value
    }
    /** ... **/
}

However, there is still an issue with your code. Your interface is not declaring any parameter in the fromColumn function, which will cause an error in the fromColumn function defined in your UserService. You might want to add the columns parameter to your fromColumn interface :

interface ToTable<T> {
    fromColumn(columns: Column[]):T
    /** ... **/
}

class UserService implements ToTable<User> {
    value: User

    constructor() {
        this.value = new User()
    }

    fromColumn(columns: Column[]): User {
        return this.value
    }
    /** ... **/
}

Here is the playground I've use to test your code

Nicolas
  • 8,077
  • 4
  • 21
  • 51
  • Thank You, it works. After deleting types and adding params to "fromColumn" methods it works. – irek Nov 29 '21 at 18:33