Yurii Hierts
Yurii Hierts

Reputation: 1920

How to say to typescript type of this, when using bind?

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.

Upvotes: 3

Views: 4508

Answers (2)

Alex Wayne
Alex Wayne

Reputation: 187004

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

Upvotes: 2

Yurii Hierts
Yurii Hierts

Reputation: 1920

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

Upvotes: 1

Related Questions