Consider the following code, which uses TypeScript language features introduced in v2.8 (conditional types):
type P<TObject, TPropertySuperType> = {
    [K in keyof TObject]: TObject[K] extends TPropertySuperType ? K : never;
}[keyof TObject];
function g<
    T,
    K extends keyof Pick<T, P<T, string>>
    >(obj: T, prop: K): void { }
class C {
    public alpha: string;
    public beta: number;
    public f(): void {
        g(this, "alpha"); // <-- does not compile!
        g(this, "beta");
        g<C, "alpha">(this, "alpha");
        g<C, "beta">(this, "beta");
        g(new C(), "alpha");
        g(new C(), "beta");
        this.g2("alpha");
        this.g2("beta");
        this.g2<"alpha">("alpha");
        this.g2<"beta">("beta");
    }
    public g2<
        K extends keyof Pick<C, P<C, string>>
        >(prop: K) { }
}
The idea behind the type P is that it selects the names of the properties of TObject that satisfy the constraint that the type of the property extends TPropertySuperType. The functions g and g2 then use the type P in a type parameter constraint, such that:
g when the prop parameter is the name of a extends string-typed property of obj
g2 when the prop parameter is the name of a extends string-typed property of C.Here, because C.alpha is of type string and C.beta is of type number, I would expect all five invocations of g/g2 with prop === "alpha" to compile, and all five invocations with prop === "beta" not to compile.
However, the invocation g(this, "alpha") does not compile, as you can see if you paste this code into the TypeScript playground. The error is:
Argument of type '"alpha"' is not assignable to parameter of type 'this[keyof this] extends string ? keyof this : never'.
Why does this particular invocation fail? I'm guessing it has something to do with how TypeScript infers the type of this, but the details are fuzzy to me.
I agree with arthem the most likely culprit is polymorphic this. While obvious the type of this will be polymorphic this. While you can say for sure C['alpha'] is of type string, for this['alpha'] you can't say that, all you can say is that this['alpha'] extends string which is a more complicated relation for the compiler to follow. Not sure if this analogy helps, but polymorphic this acts like a hidden type parameter to the class, and using it is subject to similar limitations. For example, inside g the type of obj['prop'] is not known to be string again because of limitations of what can be said for generic type parameters: 
function g<
    T,
    K extends keyof Pick<T, P<T, string>>
    >(obj: T, prop: K): void {  obj[prop].charAt(0) /*error*/}
While the above is speculation (and I'll admit a bit fuzzy), the solution that solves the error above will solve the issue with this namely to put our constraint that only string keys can be passed in in a different way. 
function g3<
    K extends string | number | symbol,
    T extends Record<K, string>
    >(obj: T, prop: K): void {   obj[prop].charAt(0) /* ok*/ }
class C {
    public alpha!: string;
    public beta!: number;
    public f(): void {
        g3(this, "alpha"); // also ok as expected
        g3(this, "beta"); //not ok
    }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With