angular/packages/compiler-cli
Paul Gschwendtner 8908fcd809 refactor(compiler-cli): initial type-checking for signal inputs (#53521)
This commit introduces the initial type-checking for signal inputs.
To enable type-checking od signal inputs, there are a couple of tricks
needed. It's not trivial as it would look like at first glance.

Initial attempts could have been to generate additional statements in
type-checking blocks for signal inputs to simply call a method like
`InputSignal#applyNewValue`. This would seem natural, as it would match
what will happen at runtime, but this would break the language-service
auto completion in a highly subtle way. Consider the case where multiple
directives match the same input. Consider the directives have some
overlap in accepted input values, but they also have distinct diverging
values, like:

```ts
class DirA {
  value = input<'apple'|'shared'>();
}

class DirB {
  value = input<'orange'|'shared'>();
}
```

In such cases, auto completion for the binding expression should suggest
the following values: `apple`, `shared`, `orange` and `undefined`.

The language service achieves this by getting completions in the
type-check block where the user expression would live. This BREAKS if
we'd have multiple places where the expression from the user is used.

Two different places, or more, surface additional problems with
diagnostic collection. Previously diagnostics would surface the union
type of allowed values, but with multiple places, we'd have to work with
potentially 1+ diagnostics. This is non-ideal.

Another important consideration is test coverage. It might sound
problematic to consider the existing test infrastructure as relevant,
but in practice, we have thousands of diagnostic type check block tests
that would greatly benefit if the general emit structure would still
match conceptually. This is another bonus argument on why changing the
way inputs are applied is probably an option we should consider as a
last resort.

Ultimately, there is a good solution where we unwrap directive signal
inputs, based on metadata, and access a brand type field on the
`InputSignal`. This ensures auto-completion continues to work as is, and
also the structure of type check blocks doesn't change conceptually. In
future commits we also need to handle type-inference for generic signal
inputs.

Note: Another alternative considered, in terms of using metadata or not.
We could have type helpers to unwrap signal inputs using type helpers
like: `T extends InputSignal<any, WriteT> ? WriteT : T`. This would
allow us to drop the input signal metadata dependency, but in reality,
this has a few issues:

- users might have `@Input`'s passing around `InputSignal`'s. This is
  unlikely, but shows that the solution would not be fully correct.
- we need the metadata regardless, as we plan on accessing it at runtime
  as well, to distinguish between signal inputs and normal inputs when
  applying new values. This was not clear when this option was
  considered initially.

PR Close #53521
2023-12-13 15:44:00 -08:00
..
integrationtest refactor: fix a number of typos throughout the codebase (#52249) 2023-10-25 16:51:24 -07:00
linker refactor(compiler): emit signal input info in d.ts and generate partial compilation output (#53521) 2023-12-13 15:44:00 -08:00
ngcc refactor(compiler-cli): add back ngcc as a no-op with a warning (#50045) 2023-04-28 18:18:40 +02:00
private build: remove unneeded babel types postinstall patching (#53441) 2023-12-08 14:33:59 -08:00
src refactor(compiler-cli): initial type-checking for signal inputs (#53521) 2023-12-13 15:44:00 -08:00
test refactor(compiler): Support o.WrappedNodeExpr inside expression conversion (#53478) 2023-12-13 09:21:53 -08:00
BUILD.bazel feat(compiler): initial skeleton for API doc extraction (#51733) 2023-09-18 12:29:19 +02:00
esbuild.config.js refactor: remove __ESM_IMPORT_META_URL__ workaround now that we can use ESM (#48521) 2022-12-19 19:50:41 +00:00
index.ts feat(compiler): extract docs via exports (#51828) 2023-09-20 18:34:55 +02:00
package.json feat(core): support TypeScript 5.3 (#52572) 2023-11-09 22:56:41 +00:00
tsconfig-build.json refactor(compiler-cli): dismantle View Engine implementation of ngc (#44269) 2021-12-01 10:36:30 -08:00
tsconfig.json build: update tsconfigs to use ES2020 as target and module (#43431) 2021-10-01 18:28:42 +00:00