diff --git a/src/main/kotlin/ts2kt/TypeScriptToKotlinBase.kt b/src/main/kotlin/ts2kt/TypeScriptToKotlinBase.kt index 164a2d4..9a3788b 100644 --- a/src/main/kotlin/ts2kt/TypeScriptToKotlinBase.kt +++ b/src/main/kotlin/ts2kt/TypeScriptToKotlinBase.kt @@ -1,5 +1,6 @@ package ts2kt +import converter.replaceTypeParameters import ts2kt.kotlin.ast.* import typescriptServices.ts.ImportEqualsDeclaration import typescriptServices.ts.Symbol @@ -14,8 +15,13 @@ abstract class TypeScriptToKotlinBase( open val defaultAnnotations: List = listOf() open fun addVariable(symbol: Symbol?, name: String, type: KtType, extendsType: KtType? = null, typeParams: List? = null, isVar: Boolean = true, needsNoImpl: Boolean = true, additionalAnnotations: List = listOf(), isOverride: Boolean = false) { + val (typeParamsToKeep, typeParamsToReplace) = (typeParams ?: emptyList()).partition { + typeParam -> extendsType?.typeArgs?.any { it.qualifiedName.name == typeParam.name } ?: false + } + val substitution = typeParamsToReplace.map { it.name.value to (it.upperBound ?: KtType(ANY)).copy(comment = it.name.value) }.toMap() + val annotations = defaultAnnotations + additionalAnnotations - addDeclaration(symbol, KtVariable(KtName(name), KtTypeAnnotation(type), extendsType?.let { KtHeritageType(it) }, annotations, typeParams, isVar = isVar, needsNoImpl = needsNoImpl, isInInterface = isInterface, isOverride = isOverride, hasOpenModifier = hasMembersOpenModifier)) + addDeclaration(symbol, KtVariable(KtName(name), KtTypeAnnotation(type.replaceTypeParameters(substitution)), extendsType?.let { KtHeritageType(it) }, annotations, typeParamsToKeep, isVar = isVar, needsNoImpl = needsNoImpl, isInInterface = isInterface, isOverride = isOverride, hasOpenModifier = hasMembersOpenModifier)) } open fun addFunction(symbol: Symbol?, name: String, callSignature: KtCallSignature, extendsType: KtType? = null, needsNoImpl: Boolean = true, additionalAnnotations: List = listOf(), isOverride: Boolean = false, isOperator: Boolean = false) { diff --git a/testData/interface/generics/genericOptionalMethods.d.kt b/testData/interface/generics/genericOptionalMethods.d.kt index 1d05f56..7b9ea91 100644 --- a/testData/interface/generics/genericOptionalMethods.d.kt +++ b/testData/interface/generics/genericOptionalMethods.d.kt @@ -2,6 +2,7 @@ package genericOptionalMethods external interface Foo { val methodWithOutArgs: (() -> Unit)? get() = definedExternally - val methodWithString: ((s: A) -> T)? get() = definedExternally - val methodWithManyArgs: ((n: A, settings: Bar) -> B)? get() = definedExternally + val methodWithString: ((s: Any /* A */) -> T)? get() = definedExternally + val methodWithManyArgs: ((n: T /* A */, settings: Bar) -> Any /* B */)? get() = definedExternally + val methodWithInOutArg: ((n: T /* A */) -> T /* A */)? get() = definedExternally } diff --git a/testData/interface/generics/genericOptionalMethods.d.ts b/testData/interface/generics/genericOptionalMethods.d.ts index 8b0da2c..8f69c54 100644 --- a/testData/interface/generics/genericOptionalMethods.d.ts +++ b/testData/interface/generics/genericOptionalMethods.d.ts @@ -2,4 +2,5 @@ interface Foo { methodWithOutArgs?(); methodWithString?(s: A): T; methodWithManyArgs?(n: A, settings: Bar): B; + methodWithInOutArg?(n: A): A; }