Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug report about keyof with class implements. #17822

Closed
acrazing opened this issue Aug 16, 2017 · 3 comments
Closed

Bug report about keyof with class implements. #17822

acrazing opened this issue Aug 16, 2017 · 3 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@acrazing
Copy link

TypeScript Version: 2.4.2

Code

/*!
 *
 * Copyright 2017 - acrazing
 *
 * @author acrazing joking.young@gmail.com
 * @since 2017-08-16 15:56:19
 * @version 1.0.0
 * @desc index.ts
 */

export interface IOptions {
  name: string;
}

export function config<T extends IOptions, K extends keyof T>(key: K, value: T[K]): void {
  console.log(key, value)
}

export interface IClass {
  config<T extends IOptions, K extends keyof T>(key: K, value: T[K]): void;
}

export class Class implements IClass {
  config<T extends IOptions, K extends keyof T>(key: K, value: T[K]): void {
    console.log(key, value)
  }
}

Expected behavior:

No Error

Actual behavior:

index.ts(23,14): error TS2420: Class 'Class' incorrectly implements interface 'IClass'.
  Types of property 'config' are incompatible.
    Type '<T extends IOptions, K extends keyof T>(key: K, value: T[K]) => void' is not assignable to type '<T extends IOptions, K extends keyof T>(key: K, value: T[K]) => void'. Two different types with this name exist, but they are unrelated.
      Types of parameters 'key' and 'key' are incompatible.
        Type 'K' is not assignable to type '"name"'.
          Type 'keyof T' is not assignable to type '"name"'.
@aluanhaddad
Copy link
Contributor

This seems to work in 2.3.3 and error in nightly.

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Aug 16, 2017
@ahejlsberg
Copy link
Member

This is working as intended and is an effect of #16368. When relating the config methods in the example it isn't possible for the checker to conclude that the T type parameters are related because no parameters use T in a manner from which inferences can be made. This also means that in calls to config it isn't possible to infer type arguments for T, so such calls will always just default to the IOptions bound unless type arguments are explicitly specified--which in turn means the T type argument is pretty much pointless.

I suggest changing the declarations to:

export function config<K extends keyof IOptions>(key: K, value: IOptions[K]): void {
  console.log(key, value)
}

export interface IClass {
  config<K extends keyof IOptions>(key: K, value: IOptions[K]): void;
}

export class Class implements IClass {
  config<K extends keyof IOptions>(key: K, value: IOptions[K]): void {
    console.log(key, value)
  }
}

@ahejlsberg ahejlsberg added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Bug A bug in TypeScript labels Aug 18, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Sep 18, 2017

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@mhegazy mhegazy closed this as completed Sep 18, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

5 participants