@@ -10,6 +10,7 @@ import {
1010 ReflectionKind ,
1111 SignatureReflection ,
1212 TypeParameterReflection ,
13+ VarianceModifier ,
1314} from "../../models" ;
1415import type { Context } from "../context" ;
1516import { ConverterEvents } from "../converter-events" ;
@@ -236,11 +237,20 @@ function convertTypeParameters(
236237 const defaultType = defaultT
237238 ? context . converter . convertType ( context , defaultT )
238239 : void 0 ;
240+
241+ // There's no way to determine directly from a ts.TypeParameter what it's variance modifiers are
242+ // so unfortunately we have to go back to the node for this...
243+ const variance = getVariance (
244+ param . getSymbol ( ) ?. declarations ?. find ( ts . isTypeParameterDeclaration )
245+ ?. modifiers
246+ ) ;
247+
239248 const paramRefl = new TypeParameterReflection (
240249 param . symbol . name ,
241250 constraint ,
242251 defaultType ,
243- parent
252+ parent ,
253+ variance
244254 ) ;
245255 context . registerReflection ( paramRefl , param . getSymbol ( ) ) ;
246256 context . trigger ( ConverterEvents . CREATE_TYPE_PARAMETER , paramRefl ) ;
@@ -253,28 +263,54 @@ export function convertTypeParameterNodes(
253263 context : Context ,
254264 parameters : readonly ts . TypeParameterDeclaration [ ] | undefined
255265) {
256- return parameters ?. map ( ( param ) => {
257- const constraint = param . constraint
258- ? context . converter . convertType ( context , param . constraint )
259- : void 0 ;
260- const defaultType = param . default
261- ? context . converter . convertType ( context , param . default )
262- : void 0 ;
263- const paramRefl = new TypeParameterReflection (
264- param . name . text ,
265- constraint ,
266- defaultType ,
267- context . scope
268- ) ;
269- context . registerReflection ( paramRefl , param . symbol ) ;
270- context . trigger (
271- ConverterEvents . CREATE_TYPE_PARAMETER ,
272- paramRefl ,
273- param
274- ) ;
266+ return parameters ?. map ( ( param ) =>
267+ createTypeParamReflection ( param , context )
268+ ) ;
269+ }
275270
276- return paramRefl ;
277- } ) ;
271+ export function createTypeParamReflection (
272+ param : ts . TypeParameterDeclaration ,
273+ context : Context
274+ ) {
275+ const constraint = param . constraint
276+ ? context . converter . convertType ( context , param . constraint )
277+ : void 0 ;
278+ const defaultType = param . default
279+ ? context . converter . convertType ( context , param . default )
280+ : void 0 ;
281+ const paramRefl = new TypeParameterReflection (
282+ param . name . text ,
283+ constraint ,
284+ defaultType ,
285+ context . scope ,
286+ getVariance ( param . modifiers )
287+ ) ;
288+ context . registerReflection ( paramRefl , param . symbol ) ;
289+ context . trigger ( ConverterEvents . CREATE_TYPE_PARAMETER , paramRefl , param ) ;
290+ return paramRefl ;
291+ }
292+
293+ function getVariance (
294+ modifiers : ts . ModifiersArray | undefined
295+ ) : VarianceModifier | undefined {
296+ const hasIn = modifiers ?. some (
297+ ( mod ) => mod . kind === ts . SyntaxKind . InKeyword
298+ ) ;
299+ const hasOut = modifiers ?. some (
300+ ( mod ) => mod . kind === ts . SyntaxKind . OutKeyword
301+ ) ;
302+
303+ if ( hasIn && hasOut ) {
304+ return VarianceModifier . inOut ;
305+ }
306+
307+ if ( hasIn ) {
308+ return VarianceModifier . in ;
309+ }
310+
311+ if ( hasOut ) {
312+ return VarianceModifier . out ;
313+ }
278314}
279315
280316function convertPredicate (
0 commit comments