@@ -253,62 +253,33 @@ describe('signalStore', () => {
253
253
) ;
254
254
} ) ;
255
255
256
- it ( 'fails when nested state slices contain Function properties' , ( ) => {
257
- expectSnippet ( `
258
- const Store = signalStore(withState({ x: { name?: '' } }));
259
- ` ) . toFail (
260
- / @ n g r x \/ s i g n a l s : n e s t e d s t a t e s l i c e s c a n n o t c o n t a i n ` F u n c t i o n ` p r o p e r t y o r m e t h o d n a m e s /
261
- ) ;
262
-
263
- expectSnippet ( `
264
- const Store = signalStore(withState({ x: { arguments: [] } }));
265
- ` ) . toFail (
266
- / @ n g r x \/ s i g n a l s : n e s t e d s t a t e s l i c e s c a n n o t c o n t a i n ` F u n c t i o n ` p r o p e r t y o r m e t h o d n a m e s /
267
- ) ;
268
-
269
- expectSnippet ( `
270
- const Store = signalStore(
271
- withState({ x: { bar: { call: false }, baz: 1 } })
272
- );
273
- ` ) . toFail (
274
- / @ n g r x \/ s i g n a l s : n e s t e d s t a t e s l i c e s c a n n o t c o n t a i n ` F u n c t i o n ` p r o p e r t y o r m e t h o d n a m e s /
275
- ) ;
276
-
277
- expectSnippet ( `
278
- const Store = signalStore(
279
- withState({ x: { apply: 'apply', bar: true } })
280
- )
281
- ` ) . toFail (
282
- / @ n g r x \/ s i g n a l s : n e s t e d s t a t e s l i c e s c a n n o t c o n t a i n ` F u n c t i o n ` p r o p e r t y o r m e t h o d n a m e s /
283
- ) ;
284
-
285
- expectSnippet ( `
286
- const Store = signalStore(
287
- withState({ x: { bind: { foo: 'bar' } } })
288
- );
289
- ` ) . toFail (
290
- / @ n g r x \/ s i g n a l s : n e s t e d s t a t e s l i c e s c a n n o t c o n t a i n ` F u n c t i o n ` p r o p e r t y o r m e t h o d n a m e s /
256
+ it ( 'succeeds when nested state slices contain Function properties' , ( ) => {
257
+ const snippet1 = `
258
+ type State = { x: { name?: string } };
259
+ const Store = signalStore(withState<State>({ x: { name: '' } }));
260
+ const store = new Store();
261
+ const name = store.x.name;
262
+ ` ;
263
+ expectSnippet ( snippet1 ) . toSucceed ( ) ;
264
+ expectSnippet ( snippet1 ) . toInfer (
265
+ 'name' ,
266
+ 'Signal<string | undefined> | undefined'
291
267
) ;
292
268
293
- expectSnippet ( `
269
+ const snippet2 = `
294
270
const Store = signalStore(
295
- withState({ x: { bar : { prototype: [] }; baz: 1 } })
271
+ withState({ x: { length : { name: false }, baz: 1 } })
296
272
);
297
- ` ) . toFail (
298
- / @ n g r x \/ s i g n a l s : n e s t e d s t a t e s l i c e s c a n n o t c o n t a i n ` F u n c t i o n ` p r o p e r t y o r m e t h o d n a m e s /
299
- ) ;
300
-
301
- expectSnippet ( `
302
- const Store = signalStore(withState({ x: { length: 10 } }));
303
- ` ) . toFail (
304
- / @ n g r x \/ s i g n a l s : n e s t e d s t a t e s l i c e s c a n n o t c o n t a i n ` F u n c t i o n ` p r o p e r t y o r m e t h o d n a m e s /
305
- ) ;
306
-
307
- expectSnippet ( `
308
- const Store = signalStore(withState({ x: { caller: '' } }));
309
- ` ) . toFail (
310
- / @ n g r x \/ s i g n a l s : n e s t e d s t a t e s l i c e s c a n n o t c o n t a i n ` F u n c t i o n ` p r o p e r t y o r m e t h o d n a m e s /
273
+ const store = new Store();
274
+ const length = store.x.length;
275
+ const name = store.x.length.name;
276
+ ` ;
277
+ expectSnippet ( snippet2 ) . toSucceed ( ) ;
278
+ expectSnippet ( snippet2 ) . toInfer (
279
+ 'length' ,
280
+ 'Signal<{ name: boolean; }> & Readonly<{ name: Signal<boolean>; }>'
311
281
) ;
282
+ expectSnippet ( snippet2 ) . toInfer ( 'name' , 'Signal<boolean>' ) ;
312
283
} ) ;
313
284
314
285
it ( 'succeeds when nested state slices are optional' , ( ) => {
@@ -355,8 +326,8 @@ describe('signalStore', () => {
355
326
) ;
356
327
} ) ;
357
328
358
- it ( 'fails when root state slices are optional' , ( ) => {
359
- expectSnippet ( `
329
+ it ( 'succeeds when root state slices are optional' , ( ) => {
330
+ const snippet = `
360
331
type State = {
361
332
foo?: { s: string };
362
333
bar: number;
@@ -365,26 +336,53 @@ describe('signalStore', () => {
365
336
const Store = signalStore(
366
337
withState<State>({ foo: { s: '' }, bar: 1 })
367
338
);
368
- ` ) . toFail ( / @ n g r x \/ s i g n a l s : r o o t s t a t e s l i c e s c a n n o t b e o p t i o n a l / ) ;
339
+ const store = new Store();
340
+ const foo = store.foo;
341
+ ` ;
342
+
343
+ expectSnippet ( snippet ) . toSucceed ( ) ;
344
+ expectSnippet ( snippet ) . toInfer (
345
+ 'foo' ,
346
+ 'Signal<{ s: string; } | undefined> | undefined'
347
+ ) ;
369
348
} ) ;
370
349
371
- it ( 'fails when state is an unknown record' , ( ) => {
372
- expectSnippet ( `
373
- const Store1 = signalStore(withState<{ [key: string]: number }>({}));
374
- ` ) . toFail ( / @ n g r x \/ s i g n a l s : r o o t s t a t e k e y s m u s t b e s t r i n g l i t e r a l s / ) ;
350
+ it ( 'succeeds when state is an unknown record' , ( ) => {
351
+ const snippet1 = `
352
+ const Store = signalStore(withState<{ [key: string]: number }>({}));
353
+ const store = new Store( );
375
354
376
- expectSnippet ( `
377
- const Store2 = signalStore(withState<{ [key: number]: { bar: string } }>({}));
378
- ` ) . toFail ( / @ n g r x \/ s i g n a l s : r o o t s t a t e k e y s m u s t b e s t r i n g l i t e r a l s / ) ;
355
+ const x = store.x;
356
+ const y = store.y;
357
+ ` ;
358
+ expectSnippet ( snippet1 ) . toSucceed ( ) ;
359
+ expectSnippet ( snippet1 ) . toInfer ( 'x' , 'Signal<number>' ) ;
360
+ expectSnippet ( snippet1 ) . toInfer ( 'y' , 'Signal<number>' ) ;
379
361
380
- expectSnippet ( `
381
- const Store3 = signalStore(
362
+ const snippet2 = `
363
+ const Store = signalStore(
364
+ withState<{ [key: number]: { bar: string } }>({})
365
+ );
366
+ const store = new Store();
367
+ const x = store[0];
368
+ const y = store[1];
369
+ ` ;
370
+ expectSnippet ( snippet2 ) . toSucceed ( ) ;
371
+ expectSnippet ( snippet2 ) . toInfer ( 'x' , 'DeepSignal<{ bar: string; }>' ) ;
372
+ expectSnippet ( snippet2 ) . toInfer ( 'y' , 'DeepSignal<{ bar: string; }>' ) ;
373
+
374
+ const snippet3 = `
375
+ const Store = signalStore(
382
376
withState<Record<string, { foo: boolean } | number>>({
383
377
x: { foo: true },
384
378
y: 1,
385
379
})
386
380
);
387
- ` ) . toFail ( / @ n g r x \/ s i g n a l s : r o o t s t a t e k e y s m u s t b e s t r i n g l i t e r a l s / ) ;
381
+ const store = new Store();
382
+ const m = store.m;
383
+ ` ;
384
+ expectSnippet ( snippet3 ) . toSucceed ( ) ;
385
+ expectSnippet ( snippet3 ) . toInfer ( 'm' , 'Signal<number | { foo: boolean; }>' ) ;
388
386
} ) ;
389
387
390
388
it ( 'fails when state is not an object' , ( ) => {
0 commit comments