@@ -754,6 +754,8 @@ class TcbDirectiveInputsOp extends TcbOp {
754
754
dirId = this . scope . resolve ( this . node , this . dir ) ;
755
755
}
756
756
757
+ // TODO(signals): signal input with a restricted modifier
758
+
757
759
const id = this . tcb . allocateId ( ) ;
758
760
const dirTypeRef = this . tcb . env . referenceType ( this . dir . ref ) ;
759
761
if ( ! ts . isTypeReferenceNode ( dirTypeRef ) ) {
@@ -771,14 +773,42 @@ class TcbDirectiveInputsOp extends TcbOp {
771
773
dirId = this . scope . resolve ( this . node , this . dir ) ;
772
774
}
773
775
774
- // To get errors assign directly to the fields on the instance, using property access
775
- // when possible. String literal fields may not be valid JS identifiers so we use
776
- // literal element access instead for those cases.
777
- target = this . dir . stringLiteralInputFields . has ( fieldName ) ?
778
- ts . factory . createElementAccessExpression (
779
- dirId , ts . factory . createStringLiteral ( fieldName ) ) :
780
- ts . factory . createPropertyAccessExpression (
781
- dirId , ts . factory . createIdentifier ( fieldName ) ) ;
776
+ if ( this . dir . isSignal ) {
777
+ const dirTypeRef = this . tcb . env . referenceType ( this . dir . ref ) ;
778
+ if ( ! ts . isTypeReferenceNode ( dirTypeRef ) ) {
779
+ throw new Error (
780
+ `Expected TypeReferenceNode from reference to ${ this . dir . ref . debugName } ` ) ;
781
+ }
782
+
783
+ const getSignalWriteType = this . tcb . env . referenceExternalType (
784
+ R3Identifiers . getInputSignalWriteType . moduleName ,
785
+ R3Identifiers . getInputSignalWriteType . name ) ;
786
+ if ( ! ts . isTypeReferenceNode ( getSignalWriteType ) ) {
787
+ throw new Error ( `Expected TypeReferenceNode from reference to ${
788
+ R3Identifiers . getInputSignalWriteType . name } `) ;
789
+ }
790
+
791
+ const inputFieldType = ts . factory . createIndexedAccessTypeNode (
792
+ ts . factory . createTypeQueryNode ( dirId as ts . Identifier ) ,
793
+ ts . factory . createLiteralTypeNode ( ts . factory . createStringLiteral ( fieldName ) ) ) ;
794
+
795
+ const inputWriteTypeId = this . tcb . allocateId ( ) ;
796
+ const inputWriteTypeSt = tsDeclareVariable (
797
+ inputWriteTypeId ,
798
+ ts . factory . createTypeReferenceNode ( getSignalWriteType . typeName , [ inputFieldType ] ) ) ;
799
+ this . scope . addStatement ( inputWriteTypeSt ) ;
800
+
801
+ target = inputWriteTypeId ;
802
+ } else {
803
+ // To get errors assign directly to the fields on the instance, using property access
804
+ // when possible. String literal fields may not be valid JS identifiers so we use
805
+ // literal element access instead for those cases.
806
+ target = this . dir . stringLiteralInputFields . has ( fieldName ) ?
807
+ ts . factory . createElementAccessExpression (
808
+ dirId , ts . factory . createStringLiteral ( fieldName ) ) :
809
+ ts . factory . createPropertyAccessExpression (
810
+ dirId , ts . factory . createIdentifier ( fieldName ) ) ;
811
+ }
782
812
}
783
813
784
814
if ( attr . attribute . keySpan !== undefined ) {
0 commit comments