Skip to content

TSC2417 - Incorrectly extending other class (which is not the case) #18643

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

Closed
rdnscr opened this issue Sep 21, 2017 · 5 comments
Closed

TSC2417 - Incorrectly extending other class (which is not the case) #18643

rdnscr opened this issue Sep 21, 2017 · 5 comments
Labels
Needs More Info The issue still hasn't been fully clarified

Comments

@rdnscr
Copy link

rdnscr commented Sep 21, 2017

TypeScript Version: 2.5.2

Code

@Injectable()
export class DefaultExceptionHandler extends ErrorHandler {

  constructor(protected notificationService: NotificationService) {
    super(false); // no rethrow of errors
  }
....
}

@Injectable()
export class MyExceptionHandler extends DefaultExceptionHandler {

  constructor(@Inject(dispatcher) private dispatcher: Subject<Action>, notificationService: NotificationService) {
    super(notificationService);
  }
....
}

Expected behavior:
This should work since it is inheritance as it is intended. It shoud be possible to have different constructor parameters to the class i extend from.

This example was working with Typescript 2.4.2 and with TypeScript 2.5.2 it is broken.

Actual behavior:

ERROR in [at-loader] ./src/app/common/services/my-exception-handler.service.ts:7:14
    TS2417: Class static side 'typeof MyExceptionHandler' incorrectly extends base class static side 'typeof DefaultExceptionHandler'.
  Types of property 'ctorParameters' are incompatible.
    Type '() => ({ type: typeof Subject; decorators: { type: InjectDecorator; args: OpaqueToken[]; }[]; } |...' is not assignable to type '() => { typ
e: typeof NotificationService; }[]'.
      Type '({ type: typeof Subject; decorators: { type: InjectDecorator; args: OpaqueToken[]; }[]; } | { typ...' is not assignable to type '{ type: t
ypeof NotificationService; }[]'.
        Type '{ type: typeof Subject; decorators: { type: InjectDecorator; args: OpaqueToken[]; }[]; } | { type...' is not assignable to type '{ type:
 typeof NotificationService; }'.
          Type '{ type: typeof Subject; decorators: { type: InjectDecorator; args: OpaqueToken[]; }[]; }' is not assignable to type '{ type: typeof No
tificationService; }'.
            Types of property 'type' are incompatible.
              Type 'typeof Subject' is not assignable to type 'typeof NotificationService'.
                Property 'ctorParameters' is missing in type 'typeof Subject'.
@mhegazy
Copy link
Contributor

mhegazy commented Sep 21, 2017

The error talks about a static property ctorParameters which is not in your code sample. please provide a self-contained reproduction of the issue.

@mhegazy mhegazy added the Needs More Info The issue still hasn't been fully clarified label Sep 21, 2017
@rdnscr
Copy link
Author

rdnscr commented Sep 25, 2017

I found the issue. The problem is the AoT compiler of angular which will generate these static ctorParameters during his compilation cycle. The typescript compiler will start his work afterwards and then breaks with the exception above.
Reason behind that is, that both classes are annotated with the @Injectable decorator since they both can be directly registered to the angular dependency injection system and therefore the AoT compiler will generate this static variables in both cases.

The only solution for this would be if typescript provides a possibility to ignore the check for statically variables, the AoT compiler of angular changes his behavior (i assume both of this changes will not happen) or if you want to derive from another angular service you use the decorator pattern instead of inheritance.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 9, 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 Oct 9, 2017
@SinoBoeckmann
Copy link

TypeScript Version: 2.6.2

Code

class SpecialClassName {
  public static breakout(): string {
    return '';
  };
};
class ExtendSpecialClassName extends SpecialClassName {
  public static breakout(title: string): string {
    return title;
  };
};

let title: string = ExtendSpecialClassName.breakout('Hi there');
console.log(name);

Expected behavior:

This should work since it is inheritance as it is intended. It should be possible to have different constructor parameters to the class i extend from.

(Actually the same as @rdnscr mentioned before; now with a working example)

Actual behavior:

typescript SinoBoeckmann$ tsc index.ts 
index.ts(7,7): error TS2417: Class static side 'typeof ExtendSpecialClassName' incorrectly extends base class static side 'typeof SpecialClassName'.
  Types of property 'breakout' are incompatible.
    Type '(title: string) => string' is not assignable to type '() => string'.

@mhegazy
Copy link
Contributor

mhegazy commented Jan 24, 2018

@SinoBoeckmann please see #4628

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Needs More Info The issue still hasn't been fully clarified
Projects
None yet
Development

No branches or pull requests

3 participants