@@ -31,10 +31,10 @@ import { expectType } from 'tsd';
3131 } ,
3232 } ) ;
3333
34- expectType < React . FC > ( VariableInput ) ;
34+ < VariableInput /> ;
3535}
3636
37- // variant catches incompatible props between cases
37+ // variant allows to pass incompatible props between cases - resulting component will have union of all props from all cases
3838{
3939 const Input : React . FC < {
4040 value : string ;
@@ -56,12 +56,38 @@ import { expectType } from 'tsd';
5656 } ,
5757 cases : {
5858 input : Input ,
59- // @ts -expect-error
6059 datetime : DateTime ,
6160 } ,
6261 } ) ;
6362
64- expectType < React . FC > ( VariableInput ) ;
63+ < VariableInput /> ;
64+ < VariableInput value = "test" /> ;
65+ < VariableInput
66+ value = "test"
67+ onChange = { ( event : { target : { value : string } } ) => {
68+ event . target . value ;
69+ } }
70+ /> ;
71+ < VariableInput
72+ value = "test"
73+ onChange = { ( ) => {
74+ // ok
75+ } }
76+ /> ;
77+ < VariableInput
78+ value = "test"
79+ onChange = { ( event : string ) => {
80+ event ;
81+ } }
82+ /> ;
83+ < VariableInput
84+ // @ts -expect-error
85+ value = { 42 }
86+ // @ts -expect-error
87+ onChange = { ( event : number ) => {
88+ event ;
89+ } }
90+ /> ;
6591}
6692
6793// variant allows not to set every possble case
@@ -89,7 +115,10 @@ import { expectType } from 'tsd';
89115 default : NotFoundPage ,
90116 } ) ;
91117
92- expectType < React . FC > ( CurrentPage ) ;
118+ < CurrentPage /> ;
119+ < CurrentPage context = { { route : 'home' } } /> ;
120+ // @ts -expect-error
121+ < CurrentPage context = "kek" /> ;
93122}
94123
95124// variant warns about wrong cases
@@ -117,7 +146,10 @@ import { expectType } from 'tsd';
117146 default : NotFoundPage ,
118147 } ) ;
119148
120- expectType < React . FC > ( CurrentPage ) ;
149+ < CurrentPage /> ;
150+ < CurrentPage context = { { route : 'home' } } /> ;
151+ // @ts -expect-error
152+ < CurrentPage context = "kek" /> ;
121153}
122154
123155// overload for boolean source
@@ -140,14 +172,21 @@ import { expectType } from 'tsd';
140172 else : FallbackPage ,
141173 bind : { context : $ctx } ,
142174 } ) ;
143- expectType < React . FC > ( CurrentPageThenElse ) ;
175+
176+ < CurrentPageThenElse /> ;
177+ < CurrentPageThenElse context = { { route : 'home' } } /> ;
178+ // @ts -expect-error
179+ < CurrentPageThenElse context = "kek" /> ;
144180
145181 const CurrentPageOnlyThen = variant ( {
146182 if : $enabled ,
147183 then : HomePage ,
148184 bind : { context : $ctx } ,
149185 } ) ;
150- expectType < React . FC > ( CurrentPageOnlyThen ) ;
186+ < CurrentPageOnlyThen /> ;
187+ < CurrentPageOnlyThen context = { { route : 'home' } } /> ;
188+ // @ts -expect-error
189+ < CurrentPageOnlyThen context = "kek" /> ;
151190}
152191
153192// supports nesting
@@ -169,6 +208,8 @@ import { expectType } from 'tsd';
169208 } ) ,
170209 } ,
171210 } ) ;
211+
212+ < NestedVariant /> ;
172213}
173214
174215// allows variants of compatible types
@@ -188,6 +229,10 @@ import { expectType } from 'tsd';
188229 } ) ,
189230 else : Loader ,
190231 } ) ;
232+
233+ < View test = "test" /> ;
234+ // @ts -expect-error
235+ < View test = { 42 } /> ;
191236}
192237
193238// Issue #81 reproduce 1
@@ -264,7 +309,6 @@ import { expectType } from 'tsd';
264309 } ,
265310 cases : {
266311 button : Button < 'button' > ,
267- // @ts -expect-error
268312 a : Button < 'a' > ,
269313 } ,
270314 } ) ;
@@ -277,15 +321,67 @@ import { expectType } from 'tsd';
277321 } ,
278322 cases : {
279323 button : Button < 'button' > ,
280- // @ts -expect-error
281324 a : Button < 'a' > ,
282325 } ,
283326 } ) ;
284327
328+ < ReflectedVariantBad /> ;
329+ < ReflectedVariantBad size = "xl" /> ;
330+ // @ts -expect-error
331+ < ReflectedVariantBad size = { 52 } /> ;
332+
285333 const IfElseVariant = variant ( {
286334 if : createStore ( true ) ,
287335 then : Button < 'button' > ,
288336 // @ts -expect-error
289337 else : Button < 'a' > ,
290338 } ) ;
339+
340+ < IfElseVariant /> ;
341+ < IfElseVariant size = "xl" /> ;
342+ // @ts -expect-error
343+ < IfElseVariant size = { 52 } /> ;
344+ }
345+
346+ // variant should allow not-to pass required props - as they can be added later in react
347+ {
348+ const Input : React . FC < {
349+ value : string ;
350+ onChange : ( newValue : string ) => void ;
351+ color : 'red' ;
352+ } > = ( ) => null ;
353+ const $variants = createStore < 'input' | 'fallback' > ( 'input' ) ;
354+ const Fallback : React . FC < { kek ?: string } > = ( ) => null ;
355+ const $value = createStore < string > ( '' ) ;
356+ const changed = createEvent < string > ( ) ;
357+
358+ const InputBase = reflect ( {
359+ view : Input ,
360+ bind : {
361+ value : $value ,
362+ onChange : changed ,
363+ } ,
364+ } ) ;
365+
366+ const ReflectedInput = variant ( {
367+ source : $variants ,
368+ cases : {
369+ input : InputBase ,
370+ fallback : Fallback ,
371+ } ,
372+ } ) ;
373+
374+ const App : React . FC = ( ) => {
375+ // missing prop must still be required in react
376+ // but in this case it is not required, as props are conditional union
377+ return < ReflectedInput /> ;
378+ } ;
379+
380+ < ReflectedInput kek = "kek" /> ;
381+
382+ const AppFixed : React . FC = ( ) => {
383+ return < ReflectedInput color = "red" /> ;
384+ } ;
385+ expectType < React . FC > ( App ) ;
386+ expectType < React . FC > ( AppFixed ) ;
291387}
0 commit comments