1
1
import { _CONST_PROPS , _IMMUTABLE } from '../shared/utils/constants' ;
2
2
import { assertEqual } from '../shared/error/assert' ;
3
3
import { isObject } from '../shared/utils/types' ;
4
- import { isSignal } from './signal.public' ;
4
+ import { isSignal , type Signal } from './signal.public' ;
5
5
import { getStoreTarget } from './impl/store' ;
6
6
import { isPropsProxy } from '../shared/jsx/jsx-runtime' ;
7
7
import { WrappedSignalFlags } from './types' ;
8
8
import { WrappedSignalImpl } from './impl/wrapped-signal-impl' ;
9
9
import { AsyncComputedSignalImpl } from './impl/async-computed-signal-impl' ;
10
10
11
11
// Keep these properties named like this so they're the same as from wrapSignal
12
- const getValueProp = ( p0 : any ) => p0 . value ;
13
- const getProp = ( p0 : any , p1 : string ) => p0 [ p1 ] ;
12
+ const getValueProp = < T > ( p0 : { value : T } ) => p0 . value ;
13
+ const getProp = < T extends object , P extends keyof T > ( p0 : T , p1 : P ) => p0 [ p1 ] ;
14
14
15
- const getWrapped = ( args : any [ ] ) =>
15
+ const getWrapped = < T extends object > ( args : [ T , ( keyof T | undefined ) ? ] ) =>
16
16
new WrappedSignalImpl ( null , args . length === 1 ? getValueProp : getProp , args , null ) ;
17
17
18
+ type PropType < T extends object , P extends keyof T > = P extends keyof T
19
+ ? T [ P ]
20
+ : 'value' extends keyof T
21
+ ? T [ 'value' ]
22
+ : never ;
23
+ type WrappedProp < T extends object , P extends keyof T > = T extends Signal
24
+ ? WrappedSignalImpl < PropType < T , P > >
25
+ : PropType < T , P > ;
26
+
18
27
/**
19
28
* This wraps a property access of a possible Signal/Store into a WrappedSignal. The optimizer does
20
29
* this automatically when a prop is only used as a prop on JSX.
@@ -26,7 +35,9 @@ const getWrapped = (args: any[]) =>
26
35
*
27
36
* @internal
28
37
*/
29
- export const _wrapProp = < T extends Record < any , any > , P extends keyof T > ( ...args : [ T , P ?] ) : any => {
38
+ export const _wrapProp = < T extends object , P extends keyof T > (
39
+ ...args : [ T , P ?]
40
+ ) : WrappedProp < T , P > => {
30
41
const obj = args [ 0 ] ;
31
42
const prop = args . length < 2 ? 'value' : args [ 1 ] ! ;
32
43
@@ -37,37 +48,34 @@ export const _wrapProp = <T extends Record<any, any>, P extends keyof T>(...args
37
48
if ( ! ( obj instanceof AsyncComputedSignalImpl ) ) {
38
49
assertEqual ( prop , 'value' , 'Left side is a signal, prop must be value' ) ;
39
50
}
40
- if ( obj instanceof WrappedSignalImpl && obj . flags & WrappedSignalFlags . UNWRAP ) {
41
- return obj ;
51
+ if ( obj instanceof WrappedSignalImpl && obj . $ flags$ & WrappedSignalFlags . UNWRAP ) {
52
+ return obj as WrappedProp < T , P > ;
42
53
}
43
- return getWrapped ( args ) ;
54
+ return getWrapped ( args ) as WrappedProp < T , P > ;
44
55
}
45
56
if ( isPropsProxy ( obj ) ) {
46
- const constProps = obj [ _CONST_PROPS ] as any ;
57
+ const constProps = obj [ _CONST_PROPS ] ;
47
58
if ( constProps && prop in constProps ) {
48
59
// Const props don't need wrapping
49
- return constProps [ prop ] ;
60
+ return constProps [ prop as keyof typeof constProps ] as WrappedProp < T , P > ;
50
61
}
51
62
} else {
52
63
const target = getStoreTarget ( obj ) ;
53
64
if ( target ) {
54
- const value = target [ prop ] ;
65
+ const value = target [ prop as P ] ;
55
66
const wrappedValue = isSignal ( value )
56
67
? // If the value is already a signal, we don't need to wrap it again
57
68
value
58
69
: getWrapped ( args ) ;
59
- return wrappedValue ;
70
+ return wrappedValue as WrappedProp < T , P > ;
60
71
}
61
72
}
62
73
// the object is not reactive, so we can just return the value
63
- return obj [ prop ] ;
74
+ return obj [ prop as P ] as WrappedProp < T , P > ;
64
75
} ;
65
76
66
77
/** @internal @deprecated v1 compat */
67
- export const _wrapSignal = < T extends Record < any , any > , P extends keyof T > (
68
- obj : T ,
69
- prop : P
70
- ) : any => {
78
+ export const _wrapSignal = < T extends object , P extends keyof T > ( obj : T , prop : P ) => {
71
79
const r = _wrapProp ( obj , prop ) ;
72
80
if ( r === _IMMUTABLE ) {
73
81
return obj [ prop ] ;
0 commit comments