Search code examples
typescriptinterfacetypescript-class

Property does not exist on type, when it clearly does


I'm writing my code in Typescript, and I'm trying to access property named id on any object that implements an interface named ObjectTemplate.

Let's say I have an class Player, that implements ObjectTemplate, that has an id property. Then, I pass new Player() into addObject() function I have provided below.

When I try to access the new Player().id (or as I named it in my parameter, obj.id), I get an error telling me that Property 'id' does not exist on type 'ObjectTemplate'

interface ObjectTemplate {
    id: string
}

class Player implements ObjectTemplate {
    id: string
    name: string
    
    constructor(name: string) {
        this.name = name
    }
}

class Entity implements ObjectTemplate {
    id: string
    health: number
    
    constructor(health: number) {
        this.health = health
    }
}

const createId = () => 'randomId'


class ObjectList<ObjectTemplate> {
    objects: { [key: string]: ObjectTemplate }

    constructor() {
        this.objects = {}
    }

    addObject(obj: ObjectTemplate) {
        const newId = createId()
        
        obj.id = newId // I get an error here.
        
        this.objects[newId] = obj
    }
}

const playerList: ObjectList<Player> = new ObjectList()
playerList.addObject(new Player("someName"))

const entityList: ObjectList<Entity> = new ObjectList()
entityList.addObject(new Entity(100))

Playground


Solution

  • I think your template syntax is wrong. You're declaring ObjectList with a new type named ObjectTemplate, and not a type that implements/extends ObjectTemplate.

    interface ObjectTemplate {
        id: string
    }
    
    class Player implements ObjectTemplate {
        id: string
        name: string
        
        constructor(name: string) {
            this.id = '0';
            this.name = name
        }
    }
    
    class Entity implements ObjectTemplate {
        id: string
        health: number
        
        constructor(health: number) {
            this.id = '0';
            this.health = health
        }
    }
    
    const createId = () => 'randomId'
    
    
    class ObjectList<T extends ObjectTemplate> {
        objects: { [key: string]: T }
    
        constructor() {
            this.objects = {}
        }
    
        addObject(obj: T) {
            const newId = createId()
            
            obj.id = newId // I get an error here.
            
            this.objects[newId] = obj
        }
    }
    
    const playerList: ObjectList<Player> = new ObjectList()
    playerList.addObject(new Player("someName"))
    
    const entityList: ObjectList<Entity> = new ObjectList()
    entityList.addObject(new Entity(100))
    

    I don't know typescript, but this is what I got from reading the docs: https://www.typescriptlang.org/docs/handbook/generics.html