3

I have 3 files with next content:

bark.ts

export function bark () {
  console.log('My name', this.name);
}

Dog.ts

import {bark} from './bark';

class Dog {
  name = 'Hachiko';
  
  makeVoice = bark.bind(this);
}

index.ts

const dog = new Dog();
dog.makeVoice();

This example is working if I run it using clean JS (without TS). But when I use this example with typescript, this has unknown type - compilation error. So how to say to TS compiler type of this in file bark.ts.

Yuriy Gyerts
  • 1,464
  • 18
  • 30

2 Answers2

2

What you want is a constraint for this. You can set that on the magic argument this in the function signature.

function(this: SomeType) {}

Now in this case, your method only cares about the name property. So you don't need this to be Dog, you just need it to have a name property.

In other words, this in bark() needs to implement the interface { name: string }.

export function bark(this: { name: string }) {
  console.log('My name', this.name);
}

Now the rest of your code works and is typesafe. And the cool thing is that if your class does not have a name that typescript wont allow you bind this function at all:

// This class does not fit the contract of bark()
class NamelessDog {
  constructor () {
    bark.bind(this); // type error, name is a required property to use bark()
  }
  
  makeVoice = bark;
}

Playground

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
1

bark.ts

export function bark (this: Dog) {
  console.log('My name', this.name);
}

Answer found here: 'this' implicitly has type 'any' because it does not have a type annotation

Yuriy Gyerts
  • 1,464
  • 18
  • 30