fix(ivy): generate type references to a default import (#29146)

This commit refactors and expands ngtsc's support for generating imports of
values from imports of types (this is used for example when importing a
class referenced in a type annotation in a constructor).

Previously, this logic handled "import {Foo} from" and "import * as foo
from" style imports, but failed on imports of default values ("import
Foo from"). This commit moves the type-to-value logic to a separate file and
expands it to cover the default import case. Doing this also required
augmenting the ImportManager to track default as well as non-default import
generation. The APIs were made a little cleaner at the same time.

PR Close #29146
This commit is contained in:
Alex Rickabaugh
2019-03-06 16:35:08 -08:00
committed by Kara Erickson
parent 37c5a26421
commit b6f6b1178f
14 changed files with 349 additions and 156 deletions

View File

@ -1970,6 +1970,34 @@ describe('ngtsc behavioral tests', () => {
expect(jsContents).toMatch(setClassMetadataRegExp('type: i\\d\\.MyTypeB'));
});
it('should use default-imported types if they can be represented as values', () => {
env.tsconfig({});
env.write(`types.ts`, `
export default class Default {}
export class Other {}
`);
env.write(`test.ts`, `
import {Component} from '@angular/core';
import {Other} from './types';
import Default from './types';
@Component({selector: 'test', template: 'test'})
export class SomeCmp {
constructor(arg: Default, other: Other) {}
}
`);
env.driveMain();
const jsContents = trim(env.getContents('test.js'));
expect(jsContents).toContain(`import i1 from "./types";`);
expect(jsContents).toContain(`import * as i2 from "./types";`);
expect(jsContents).toContain('i0.ɵdirectiveInject(i1)');
expect(jsContents).toContain('i0.ɵdirectiveInject(i2.Other)');
expect(jsContents).toMatch(setClassMetadataRegExp('type: i1'));
expect(jsContents).toMatch(setClassMetadataRegExp('type: i2.Other'));
});
it('should use `undefined` in setClassMetadata if types can\'t be represented as values', () => {
env.tsconfig({});