Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
430 views
in Technique[技术] by (71.8m points)

typescript - Extract utility type breaks with "this"

I am trying to write an instance method in Typescript that accepts the name of one of the instance's attributes, but only if that attribute's name is a string. Why does this.doStuff("name") fail to compile?

Below is the shortest example I could come up with.

type StringAttributes<T> = Extract<keyof T, string>;

class Base {
  1337: string;
  name!: string;

  doStuff(attr: StringAttributes<this>): void {
    console.log(this[attr]);
  }

  doEverything() {
    const bar = new Base();
    // should compile
    bar.doStuff("name");

    // should compile (but doesn't)
    this.doStuff("name");

    // should not compile
    bar.doStuff("fizzbuzz");
    this.doStuff("fizzbuzz");

    // should not compile
    this.doStuff(1337);
    bar.doStuff(1337);
  }

  doEverythingWithType(this: Base) {
    const bar = new Base();
    // should compile
    bar.doStuff("name");

    // should compile
    this.doStuff("name");

    // should not compile
    bar.doStuff("fizzbuzz");
    this.doStuff("fizzbuzz");

    // should not compile
    this.doStuff(1337);
    bar.doStuff(1337);
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your StringAttributes requires typescript to fully evaluate keyof this, which it can't do. Instead, use a generic with a bound:

doStuff<T extends keyof this & string>(attr: T): void {
  console.log(this[attr]);
}

Or, as stated in the comments:

doStuff(attr: keyof this & string): void {
  console.log(this[attr]);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...