Skip to content

Commit 27bf809

Browse files
JoostKkirjs
authored andcommitted
test(core): type tests for linkedSignal (angular#60857)
This commit adds type inference tests for `linkedSignal` usages, to capture their behavior w.r.t. type inference. Note that there's some situations where type inference doesn't work as you might expect/hope; these have been included to capture their behavior but may be revisited in the future if the inference capabilities are expanded for this scenario. Closes angular#60423 PR Close angular#60857
1 parent 6b9434a commit 27bf809

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

packages/core/test/authoring/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ ts_library(
44
name = "signal_authoring_signature_test_lib",
55
testonly = True,
66
srcs = [
7+
"linked_signal_signature_test.ts",
78
"signal_input_signature_test.ts",
89
"signal_model_signature_test.ts",
910
"signal_queries_signature_test.ts",
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
/**
10+
* @fileoverview
11+
* This file contains various signal `input()` patterns and ensures
12+
* the resulting types match our expectations (via comments asserting the `.d.ts`).
13+
*/
14+
15+
import {signal, linkedSignal} from '@angular/core';
16+
// import preserved to simplify `.d.ts` emit and simplify the `type_tester` logic.
17+
// tslint:disable-next-line no-duplicate-imports
18+
import {WritableSignal} from '@angular/core';
19+
20+
const source = signal(0);
21+
22+
declare function stringEqual(a: string, b: string): boolean;
23+
declare function numberEqual(a: number, b: number): boolean;
24+
25+
export class LinkedSignalSignatureTest {
26+
/** number */
27+
simple = linkedSignal(() => 0);
28+
29+
/** number */
30+
simpleWithCompatibleEqual = linkedSignal(source, {
31+
equal: numberEqual,
32+
});
33+
34+
/** number */
35+
simpleWithIncompatibleEqual = linkedSignal(source, {
36+
// @ts-expect-error assignability error
37+
equal: stringEqual,
38+
});
39+
40+
/** number */
41+
advanced = linkedSignal({source, computation: (s) => s * 2});
42+
43+
/** string */
44+
advancedWithCompatibleEqual = linkedSignal({
45+
source,
46+
computation: (s) => String(s),
47+
equal: (a, b) => true,
48+
});
49+
50+
/** unknown */
51+
/**
52+
* An incompatible `equal` function results in an overload resolution failure, causing the type `unknown` to be
53+
* inferred. This test aims to capture this limitation and may be revisited if this were to become supported.
54+
*/
55+
advancedWithIncompatibleEqual =
56+
// @ts-expect-error overload resolution error
57+
linkedSignal({
58+
source,
59+
// @ts-expect-error implicit any error
60+
computation: (s) => String(s),
61+
equal: numberEqual,
62+
});
63+
64+
/** unknown */
65+
/**
66+
* Due to the cyclic nature of `previous`'s type and the computation's return type, TypeScript isn't able to infer
67+
* generic type arguments. This test aims to capture this limitation and may be revisited if this were to become
68+
* supported.
69+
*
70+
* @see https://github.com/microsoft/TypeScript/issues/49618
71+
* @see https://github.com/angular/angular/issues/60423
72+
*/
73+
advancedWithPreviousImplicitGenerics = linkedSignal({
74+
source,
75+
computation: (s, previous) => String(s),
76+
});
77+
78+
/** string */
79+
advancedWithPreviousExplicitGenerics = linkedSignal<number, string>({
80+
source,
81+
computation: (s, previous) => String(s),
82+
});
83+
}

packages/core/test/authoring/type_tester.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import url from 'url';
1313

1414
/** Currently-configured tests. */
1515
const TESTS = new Map<string, (value: string) => string>([
16+
['linked_signal_signature_test', (v) => `WritableSignal<${v}>`],
1617
[
1718
'signal_input_signature_test',
1819
(v) => (v.includes(',') ? `InputSignalWithTransform<${v}>` : `InputSignal<${v}>`),

0 commit comments

Comments
 (0)