Typescript: Stricter TypeChecking with Decorators.

Created on 4 Aug 2015  ·  4Comments  ·  Source: microsoft/TypeScript

This is a common issue in Angular 2

Correct:

@Component({
  selector: 'issue',
})
@View({
  templateUrl: 'issue_component.html',
  directives: [MyDirective]
})
class MyComponent {}

Common mistake is to put the directives on the wrong decorator:

@Component({
  selector: 'issue',
  directives: [MyDirective]
})
@View({
  templateUrl: 'issue_component.html'
})
class MyComponent {}

The issue is that this passes type-checking in TypeScript because the all args are optional. The extra arg is ignored.

  interface ComponentFactory {
     new(obj: {
      selector?: string,
      properties?: List<string>,
      events?: List<string>,
      host?: StringMap<string, string>,
      lifecycle?: List<LifecycleEvent>,
      hostInjector?: List<any>,
      exportAs?: string,
      compileChildren?: boolean,
      viewInjector?: List<any>,
      changeDetection?: string,
    }): ComponentAnnotation;
  }

  interface ViewFactory {
     new(obj: {
      templateUrl?: string,
      template?: string,
      directives?: List<Type | any | List<any>>,
      renderer?: string,
      styles?: List<string>,
      styleUrls?: List<string>,
    }): ViewDecorator;
  }

Ideally we would like to say that we only allow the args which are declared and any extra arg is to be an error.

Could we have such a feature?

Most helpful comment

I am now getting this Error:

TS2345 Argument of type '{ selector: string; directives: any[]; }' is not assignable to parameter of type '{ selector?: string; properties?: string[]; events?: string[]; host?: { [x: string]: string; }; l...'.
Object literal may only specify known properties, and 'directives' does not exist in type '{ selector?: string; properties?: string[]; events?: string[]; host?: { [x: string]: string; }; l...'.

All 4 comments

Support for this was added in #3823, and is listed in the Wiki under Breaking Changes. Please verify using typescript@next and let us know if this satisfies your use case.

Looks like what we need! Awesome. Let us give it a try.

I am now getting this Error:

TS2345 Argument of type '{ selector: string; directives: any[]; }' is not assignable to parameter of type '{ selector?: string; properties?: string[]; events?: string[]; host?: { [x: string]: string; }; l...'.
Object literal may only specify known properties, and 'directives' does not exist in type '{ selector?: string; properties?: string[]; events?: string[]; host?: { [x: string]: string; }; l...'.

PERFECT!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fwanicka picture fwanicka  ·  3Comments

DanielRosenwasser picture DanielRosenwasser  ·  3Comments

CyrusNajmabadi picture CyrusNajmabadi  ·  3Comments

MartynasZilinskas picture MartynasZilinskas  ·  3Comments

jbondc picture jbondc  ·  3Comments