@@ -3527,16 +3527,18 @@ function buildTypescriptDeclarations() {
3527
3527
function exportTypescriptDeclarations ( basePath , allowedModules , include , exclude ) {
3528
3528
3529
3529
var optionInterfaceNamespaces = { } ;
3530
+ var moduleCallbackGenerics = { } ;
3531
+ var moduleOptionsGenerics = { } ;
3530
3532
3531
3533
var whitelist = getMethodList ( include ) ;
3532
3534
var blacklist = getMethodList ( exclude ) ;
3533
3535
3534
- var TYPE_GUARD_REG = / i s ( B o o l e a n | N u m b e r | S t r i n g | D a t e | R e g E x p | F u n c t i o n | A r r a y | E r r o r | S e t | M a p ) $ / ;
3536
+ var TYPE_REG = / i s ( B o o l e a n | N u m b e r | S t r i n g | D a t e | R e g E x p | F u n c t i o n | A r r a y | E r r o r | S e t | M a p ) $ / ;
3535
3537
3536
3538
var TYPE_GUARD_GENERICS = {
3537
- Array : [ 'T ' ] ,
3538
- Map : [ 'K ' , 'V ' ] ,
3539
- Set : [ 'T ' ]
3539
+ Array : [ 'any ' ] ,
3540
+ Map : [ 'any ' , 'any ' ] ,
3541
+ Set : [ 'any ' ]
3540
3542
}
3541
3543
3542
3544
var CHAINABLE_RAW_TYPE = 'RawValue' ;
@@ -3749,7 +3751,7 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
3749
3751
}
3750
3752
3751
3753
function mapType ( type ) {
3752
- return 'type ' + type . name + ' = ' + type . type + ';'
3754
+ return 'type ' + type . name + ( type . generics || '' ) + ' = ' + type . type + ';'
3753
3755
}
3754
3756
3755
3757
addBlock ( module . types , '\n' . repeat ( top ? 2 : 1 ) , mapType ) ;
@@ -3824,13 +3826,12 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
3824
3826
3825
3827
// Set up all remaining methods.
3826
3828
3827
- var instanceParam = {
3828
- name : 'instance' ,
3829
- required : true ,
3830
- type : rawType
3831
- } ;
3832
-
3833
3829
namespace . methods . forEach ( function ( method ) {
3830
+ var instanceParam = {
3831
+ name : 'instance' ,
3832
+ required : true ,
3833
+ type : getInstanceParamType ( method , rawType )
3834
+ } ;
3834
3835
var method = clone ( method ) ;
3835
3836
if ( method . type === 'instance' ) {
3836
3837
method . params . unshift ( instanceParam ) ;
@@ -3882,13 +3883,13 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
3882
3883
// Add object instance methods as static, i.e.
3883
3884
// Object.forEach, etc.
3884
3885
if ( namespace . name === 'Object' ) {
3885
- var objectInstanceParam = {
3886
- name : 'instance' ,
3887
- type : 'Object' ,
3888
- required : true
3889
- } ;
3890
3886
var objectInstanceMethods = getExtendedMethods ( namespace , 'instance' ) ;
3891
3887
getExtendedMethods ( namespace , 'instance' ) . forEach ( function ( method ) {
3888
+ var objectInstanceParam = {
3889
+ name : 'instance' ,
3890
+ type : getInstanceParamType ( method , 'Object' ) ,
3891
+ required : true
3892
+ } ;
3892
3893
method = clone ( method ) ;
3893
3894
method . params . unshift ( objectInstanceParam ) ;
3894
3895
if ( method . signatures ) {
@@ -4053,7 +4054,7 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
4053
4054
4054
4055
function getGenericSource ( generic ) {
4055
4056
if ( generic instanceof Array ) {
4056
- generic = generic . join ( ', ' ) ;
4057
+ generic = getUniqueGenerics ( generic ) . join ( ', ' ) ;
4057
4058
}
4058
4059
if ( ! generic ) {
4059
4060
return '' ;
@@ -4063,7 +4064,18 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
4063
4064
return generic ;
4064
4065
}
4065
4066
4067
+ function getUniqueGenerics ( generics ) {
4068
+ var result = [ ] ;
4069
+ generics . forEach ( function ( g ) {
4070
+ if ( g === 'any' || result . indexOf ( g ) === - 1 ) {
4071
+ result . push ( g ) ;
4072
+ }
4073
+ } ) ;
4074
+ return result ;
4075
+ }
4076
+
4066
4077
function addMethodGenerics ( method , generics ) {
4078
+ generics = generics || [ ] ;
4067
4079
if ( typeof generics === 'string' ) {
4068
4080
generics = [ generics ] ;
4069
4081
}
@@ -4080,6 +4092,14 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
4080
4092
4081
4093
/* ------------ Methods -------------- */
4082
4094
4095
+ function isTypeCheck ( method ) {
4096
+ return method . name . match ( TYPE_REG ) ;
4097
+ }
4098
+
4099
+ function getInstanceParamType ( method , type ) {
4100
+ return isTypeCheck ( method ) ? 'any' : type ;
4101
+ }
4102
+
4083
4103
function buildMethods ( methods , namespace , mode ) {
4084
4104
methods . sort ( collateMethods ) ;
4085
4105
methods = methods . map ( function ( method ) {
@@ -4113,22 +4133,32 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
4113
4133
src += ( param . type || '' ) . split ( '|' ) . map ( function ( type ) {
4114
4134
type = getType ( type , method ) || 'undefined' ;
4115
4135
if ( type . match ( / F n $ / ) ) {
4136
+ var callback = method . callbacks . find ( function ( callback ) {
4137
+ return callback . name === type ;
4138
+ } ) ;
4116
4139
if ( param . type . indexOf ( '|' ) === - 1 ) {
4117
4140
// If a callback is the ONLY type allowed for this parameter
4118
4141
// (no alternates), then it can be inlined directly into the
4119
4142
// definition, so do that here. Otherwise it needs to be moved
4120
4143
// out into a named type and referenced.
4121
- var callback = method . callbacks . find ( function ( callback ) {
4122
- return callback . name === type ;
4123
- } ) ;
4124
4144
type = getFunctionSource ( callback ) ;
4125
- } else if ( mode === 'extended' ) {
4126
- // If we are in extended mode and referencing a callback interface,
4127
- // then it needs to have its fully qualified namespace.
4128
- type = [ 'sugarjs' , namespace . name , type ] . join ( '.' ) ;
4145
+ } else {
4146
+ if ( mode === 'extended' ) {
4147
+ // If we are in extended mode and referencing a callback interface,
4148
+ // then it needs to have its fully qualified namespace.
4149
+ type = [ 'sugarjs' , namespace . name , type ] . join ( '.' ) ;
4150
+ }
4151
+ var generics = moduleCallbackGenerics [ namespace . name + ':' + callback . name ] ;
4152
+ if ( generics ) {
4153
+ addMethodGenerics ( method , generics ) ;
4154
+ type += getGenericSource ( generics ) ;
4155
+ }
4129
4156
}
4130
4157
} else if ( type . match ( / O p t i o n s $ / ) ) {
4131
4158
var optionsNamespace = optionInterfaceNamespaces [ type ] ;
4159
+ var generics = moduleOptionsGenerics [ namespace . name + ':' + type ] ;
4160
+ type += getGenericSource ( generics ) ;
4161
+ addMethodGenerics ( method , generics ) ;
4132
4162
if ( mode === 'extended' ) {
4133
4163
// If we are in extended mode and referencing an options inteface,
4134
4164
// then it needs to have its fully qualified namespace.
@@ -4160,7 +4190,7 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
4160
4190
}
4161
4191
4162
4192
function requiresTypeGuard ( ) {
4163
- return method . name . match ( TYPE_GUARD_REG ) &&
4193
+ return isTypeCheck ( method ) &&
4164
4194
( mode === 'static' || mode === 'extended' ) ;
4165
4195
}
4166
4196
@@ -4184,8 +4214,7 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
4184
4214
var type = method . name . replace ( / ^ i s / , '' ) ;
4185
4215
var generics = TYPE_GUARD_GENERICS [ type ] ;
4186
4216
if ( generics ) {
4187
- addMethodGenerics ( method , generics ) ;
4188
- type += '<' + generics . join ( ',' ) + '>' ;
4217
+ type += getGenericSource ( generics ) ;
4189
4218
}
4190
4219
src = getTypeGuard ( type ) ;
4191
4220
} else if ( ( match = src . match ( / A r r a y < ( .+ ) > / ) ) ) {
@@ -4446,9 +4475,14 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
4446
4475
return t . name === callback . name ;
4447
4476
} ) ;
4448
4477
if ( ! typeExists ) {
4478
+ var signature = getCallbackSignature ( callback , method , namespace ) ;
4479
+ if ( method . generics ) {
4480
+ moduleCallbackGenerics [ namespace . name + ':' + callback . name ] = method . generics ;
4481
+ }
4449
4482
module . types . push ( {
4450
4483
name : callback . name ,
4451
- type : getCallbackSignature ( callback , method , namespace )
4484
+ generics : getGenericSource ( callback . generics ) ,
4485
+ type : signature
4452
4486
} ) ;
4453
4487
}
4454
4488
}
@@ -4482,12 +4516,21 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
4482
4516
return param . type . match ( / O p t i o n s $ / ) ;
4483
4517
} ) ;
4484
4518
4519
+ var optionsGenerics = [ ] ;
4520
+
4485
4521
var src = method . options . map ( function ( option ) {
4486
4522
var types = option . type . split ( '|' ) ;
4487
4523
types = types . map ( function ( type ) {
4488
- if ( types . length === 1 && type . match ( / F n $ / ) ) {
4524
+ if ( type . match ( / F n $ / ) ) {
4489
4525
var callback = findMethodCallbackByName ( method , type ) ;
4490
- type = getCallbackSignature ( callback , method , namespace ) ;
4526
+ if ( types . length === 1 && type . match ( / F n $ / ) ) {
4527
+ // Inline a callback delcaration
4528
+ type = getCallbackSignature ( callback , method , namespace ) ;
4529
+ } else {
4530
+ // Refer to callback externally
4531
+ type += getGenericSource ( moduleCallbackGenerics [ namespace . name + ':' + callback . name ] ) ;
4532
+ }
4533
+ optionsGenerics = optionsGenerics . concat ( callback . generics ) ;
4491
4534
}
4492
4535
return type ;
4493
4536
} ) ;
@@ -4500,14 +4543,20 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
4500
4543
optionInterfaceNamespaces [ optionsParam . type ] = namespace . name ;
4501
4544
}
4502
4545
4503
- module . interfaces . push ( getInterfaceSource ( optionsParam . type , src ) ) ;
4546
+ moduleOptionsGenerics [ namespace . name + ':' + optionsParam . type ] = optionsGenerics ;
4547
+ var name = optionsParam . type + getGenericSource ( optionsGenerics ) ;
4548
+ module . interfaces . push ( getInterfaceSource ( name , src ) ) ;
4504
4549
} ) ;
4505
4550
}
4506
4551
4507
4552
function getCallbackSignature ( callback , method , namespace ) {
4553
+ var genericsLength = method . generic && method . generics . length || 0 , gen ;
4508
4554
var params = getParams ( callback . params , method , namespace ) ;
4509
4555
var returns = callback . returns ? getType ( callback . returns , method ) : 'void' ;
4510
- return getGenericSource ( method . generics ) + '(' + params + ') => ' + returns ;
4556
+ // Slightly convoluted way of getting generics for the callback by
4557
+ // subtracting method generics from what they were previously.
4558
+ callback . generics = method . generics . slice ( genericsLength ) ;
4559
+ return '(' + params + ') => ' + returns ;
4511
4560
}
4512
4561
4513
4562
function findMethodCallbackByName ( method , name ) {
@@ -4541,10 +4590,10 @@ function exportTypescriptDeclarations(basePath, allowedModules, include, exclude
4541
4590
sugarjs . interfaces . push ( getRangeInterface ( namespace ) ) ;
4542
4591
} else {
4543
4592
var module = getDeclaredNamespace ( namespace . name ) ;
4593
+ addExtras ( module ) ;
4544
4594
module . interfaces . push ( getConstructorInterface ( namespace , module ) ) ;
4545
4595
module . interfaces . push ( getChainableBaseInterface ( namespace ) ) ;
4546
4596
4547
- addExtras ( module ) ;
4548
4597
4549
4598
// Export extended interfaces unless opting out.
4550
4599
if ( args [ 'extended-mode' ] !== false ) {
0 commit comments