Skip to content

Design:type metadata for cyclic dependencies throw at runtime #27519

@bajtos

Description

@bajtos

TypeScript Version: 3.2.0-dev.20181003

Search Terms: design cyclic

Code

index.ts

import 'reflect-metadata';

function property() {
  return (target: Object, key: string) => {
    const t = Reflect.getMetadata('design:type', target, key);
    console.log('property %s#%s of type', target.constructor.name, key, t.name);
  }
}

class Product {
  // belongs to a category
  @property()
  category: Category;
}

class Category {
  // has many products
  @property()
  products: Product[];
}

tsconfig.json

{
  "$schema": "http://json.schemastore.org/tsconfig",
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,

    "lib": ["es2018", "dom"],
    "module": "commonjs",
    "moduleResolution": "node",
    "target": "es2017"
  },
  "include": [
    "index.ts"
  ]
}

package.json

{
  "dependencies": {
    "reflect-metadata": "^0.1.12",
    "typescript": "^3.2.0-dev.20181003"
  }
}

Expected behavior:

Ideally, the code compiles and node index.js produces the following console output:

property Product#category of type Category
property Category#products of type Array

If this is not possible, then the compiler should detect cyclic dependencies and fail the compilation with a helpful error.

Actual behavior:

The code compiles. When the compiled code is executed, it fails at runtime.

index.js:23
    __metadata("design:type", Category)
                              ^

ReferenceError: Category is not defined
    at Object.<anonymous> (index.js:23:31)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    (...)

Here is the relevant snippet from the transpiled output:

class Product {
}
__decorate([
    property(),
    __metadata("design:type", Category)
], Product.prototype, "category", void 0);

class Category {
}
__decorate([
    property(),
    __metadata("design:type", Array)
], Category.prototype, "products", void 0);

Playground Link:

Playground does not support emitDecoratorMetadata and experimentalDecorators options ☹️

Related Issues:

None found.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions