Repository navigation
Dynamic host attribute values are rejected (and two local-compilation-only transform cases) #627
Description
Summary
Three Angular ngtsc specs compile with ngtsc but get a compile error from oxc, so a Vite build fails. Found by running Angular v22.0.0's ngtsc emit specs against oxc main (04cb3b2). Only case 1 is a bug in oxc. Cases 2 and 3 compile only in ngtsc's local compilation mode. That mode skips these checks because a separate full build checks them, and oxc already matches the full-mode diagnostics on purpose (#494).
1. Dynamic host attribute value (bug)
ngtsc_spec.ts: "should accept dynamic host attribute bindings"
// other.d.ts
export declare const foo: any;
// test.ts
import {Component} from '@angular/core';
import {foo} from './other';
const test = foo.bar();
@Component({selector: 'test', template: '', host: {'test': test}})
export class TestCmp {}Actual
@Component.host depends on 'foo', which is imported from another module. OXC compiles one file at a time and cannot evaluate values from other files.
The error is the same with and without resolveImportedValues. A same-file dynamic value (host: {role: make()}) is also rejected: ... could not be determined statically. OXC does not support dynamic host attribute values.
Expected (ngc)
hostAttrs: ["test", test]Cause
evaluateHostExpressionBindings (annotations/directive/src/shared.ts) turns a DynamicValue into new WrappedNodeExpr(value.node). parseHostBindings then emits it as is for a plain attribute, and rejects it only for [prop], (event), class and style. oxc stores host attribute values as strings, so it has no way to emit an expression.
2. Input transform from a namespace import (not a bug)
local_compilation_spec.ts: "should generate input info for transform function imported externally using namespace"
import * as n from './some_where';
// ...
@Input({transform: n.externalFunc}) x: string = '';Actual: Input transform function could not be referenced Value is a reference to 'externalFunc'. Local mode emits inputs: { x: [2, "x", "x", n.externalFunc] }.
3. Inline transform with an untyped parameter (not a bug)
local_compilation_spec.ts: "should not check inline function param type"
@Input({transform: v => v + 'TRANSFORMED!'}) x: string = '';Actual: Input transform function first parameter must have a type Value could not be determined statically. Local mode emits inputs: { x: [2, "x", "x", v => v + 'TRANSFORMED!'] }.
Why 2 and 3 are not bugs
parseDecoratorInputTransformFunction skips every transform check when compilationMode === LOCAL, "because usually the type check is done in a separate build which runs in full compilation mode". In full mode, which is what ng build uses, ngtsc reports both errors:
- case 3 matches
ngtsc_spec.ts"should produce a diangostic if the transform function first parameter has no arguments" (transform: (val) => 1); - for case 2, a namespace member has no identity in the file (
getIdentityInreturns null), and feat(directive): validate input transforms like ngtsc #494 checked this against ngtsc 22.1.7 (namespace_imported_transform_cannot_be_referenced).
oxc is the only compiler in a Vite build, so no other build would check these. Dropping the checks would let code through that ng build rejects. I left both cases as they are.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Activity