fix(Generic Constraints d.ts): add to d.ts generic type parameters constraints.

This commit is contained in:
Artem Kobzar
2022-01-24 17:21:44 +01:00
committed by Space
parent 62c351874f
commit 9547b0cae1
5 changed files with 39 additions and 5 deletions
@@ -27,7 +27,7 @@ data class ExportedFunction(
val name: String,
val returnType: ExportedType,
val parameters: List<ExportedParameter>,
val typeParameters: List<String> = emptyList(),
val typeParameters: List<ExportedType.TypeParameter> = emptyList(),
val isMember: Boolean = false,
val isStatic: Boolean = false,
val isAbstract: Boolean = false,
@@ -111,7 +111,7 @@ sealed class ExportedType {
) : ExportedType()
class ClassType(val name: String, val arguments: List<ExportedType>, val ir: IrClass) : ExportedType()
class TypeParameter(val name: String) : ExportedType()
class TypeParameter(val name: String, val constraint: ExportedType? = null) : ExportedType()
class Nullable(val baseType: ExportedType) : ExportedType()
class ErrorType(val comment: String) : ExportedType()
class TypeOf(val name: String) : ExportedType()
@@ -83,7 +83,7 @@ class ExportModelGenerator(
function.getExportedIdentifier(),
returnType = exportType(function.returnType),
parameters = (listOfNotNull(function.extensionReceiverParameter) + function.valueParameters).map { exportParameter(it) },
typeParameters = function.typeParameters.map { it.name.identifier },
typeParameters = function.typeParameters.map(::exportTypeParameter),
isMember = parent is IrClass,
isStatic = function.isStaticMethodOfClass,
isAbstract = parent is IrClass && !parent.isInterface && function.modality == Modality.ABSTRACT,
@@ -441,6 +441,25 @@ class ExportModelGenerator(
return ExportedType.ErrorType("UnknownType ${type.render()}")
}
private fun exportTypeParameter(typeParameter: IrTypeParameter): ExportedType.TypeParameter {
val constraint = typeParameter.superTypes.asSequence()
.filter { it != context.irBuiltIns.anyNType }
.map(::exportType)
.filter { it !is ExportedType.ErrorType && it !is ExportedType.ImplicitlyExportedType }
.toList()
return ExportedType.TypeParameter(
typeParameter.name.identifier,
constraint.run {
when (size) {
0 -> null
1 -> single()
else -> reduce(ExportedType::IntersectionType)
}
}
)
}
private fun exportType(type: IrType): ExportedType {
if (type is IrDynamicType)
return ExportedType.Primitive.Any
@@ -77,7 +77,7 @@ fun ExportedDeclaration.toTypeScript(indent: String, prefix: String = ""): Strin
val renderedTypeParameters =
if (typeParameters.isNotEmpty())
"<" + typeParameters.joinToString(", ") + ">"
"<" + typeParameters.joinToString(", ") { it.toTypeScript(indent) } + ">"
else
""
@@ -285,7 +285,6 @@ fun ExportedType.toTypeScript(indent: String): String = when (this) {
is ExportedType.TypeOf ->
"typeof $name"
is ExportedType.TypeParameter -> name
is ExportedType.ErrorType -> "any /*$comment*/"
is ExportedType.Nullable -> "Nullable<" + baseType.toTypeScript(indent) + ">"
is ExportedType.InlineInterfaceType -> {
@@ -302,4 +301,9 @@ fun ExportedType.toTypeScript(indent: String): String = when (this) {
is ExportedType.ImplicitlyExportedType -> {
ExportedType.Primitive.Any.toTypeScript(indent) + "/* ${type.toTypeScript("")} */"
}
is ExportedType.TypeParameter -> if (constraint == null) {
name
} else {
"$name extends ${constraint.toTypeScript(indent)}"
}
}
@@ -16,6 +16,8 @@ declare namespace JS_TESTS {
function defaultParameters(x: number, y: string): string;
function generic1<T>(x: T): T;
function generic2<T>(x: Nullable<T>): boolean;
function genericWithConstraint<T extends string>(x: T): T;
function genericWithMultipleConstraints<T extends foo.TestInterface & Error>(x: T): T;
function generic3<A, B, C, D, E>(a: A, b: B, c: C, d: D): Nullable<E>;
function inlineFun(x: number, callback: (p0: number) => void): void;
const _const_val: number;
@@ -44,6 +44,15 @@ fun <T> generic1(x: T): T = x
@JsExport
fun <T> generic2(x: T?): Boolean = (x == null)
@JsExport
fun <T: String> genericWithConstraint(x: T): T = x
@JsExport
fun <T> genericWithMultipleConstraints(x: T): T
where T : Comparable<T>,
T : TestInterface,
T : Throwable = x
@JsExport
fun <A, B, C, D, E> generic3(a: A, b: B, c: C, d: D): E? = null