# Verify Generics

Type parameter vs type argument

To undersigned Konsist API let's look at the difference between `generic type parameters` and `generic type arguments`:

1. **Type Parameter** is the placeholder (like `T`) you write when *creating* a class or function (declaration site)
2. **Type Argument** is the actual type (like `String` or `Int`) you provide when *using* that class or function (use site)

Simple Examples:

```kotlin
// Example 1: Class
// Here 'T' is a TYPE PARAMETER
class Box<T>(val item: T)

// Here 'String' is a TYPE ARGUMENT
val stringBox = Box<String>("Hello")


// Example 2: Function
// Here 'T' is a TYPE PARAMETER
fun <T> printWithType(item: T) {
    println("Type is: ${item::class.simpleName}")
}

// Here 'String' and 'Int' are TYPE ARGUMENTS
printWithType<String>("Hello")  // prints: Type is: String
```

## Verify Type Parameters

Type parameters can be defined, for example, inside class or function.

### Check whether a class's generic type parameter has the name `UiState`:

```kotlin
// Code Snippet 
class View<UiState>(val state: UiState) // UiState is typeParamener 

// Konsist
Konsist
    .scopeFromProject()
    .classes()
    .typeParameters // access type parameters
    .assertTrue {
        it.name == "UiState" // true
    }
```

### Check whether function `type parameters` has `out` modifier:

<pre class="language-kotlin"><code class="lang-kotlin">//Code Snippet 
<strong>fun &#x3C;out T> setState(item: T?) {
</strong>    // ...
}

// Konsist
Konsist
    .scopeFromProject()
    .functions()
    .typeParameters // access type parameters
    .assertTrue {
        it.hasOutModifier // true
    }
</code></pre>

## Verify Type Arguments

### Check whether a property generic type argument has the name `Service`:

```kotlin
//Code Snippet 
val services: List<Service> = emptyList()

// Konsist
Konsist
    .scopeFromProject()
    .properties()
    .assertTrue { property ->
        property
            .type
            ?.typeArguments
            ?.flatten()
            ?.any { typeArgument -> typeArgument.name == "Service" }
    }
```

The `flatten()` extension method allows to flatten type parameters structure:

* For a type argument like `String`, it returns `listOf()`.
* For a type argument like `List<String>`, it returns `listOf(String)`.
* For a type argument like `Map<List<String>, Int>`, it returns `listOf("List, String, Int)`.

### Check if all functions parameters are have generic type argument ending with `UIState`:

```kotlin
// Snippet 
fun setState(uiState: View<WelcomeUIState>)

// Konsist Test
Konsist
    .scopeFromProject()
    .properties()
    .parameters
    .types
    .typeArguments
    .assertTrue { 
        it.hasNameEndingWith("UIState")  // true
    }
```

### Check all parents have \`String\` type argument:

```kotlin
// Snippet 
open class Container<T>(private val item: T) { }
class StringContainer(text: String) : Container<String>(text) { }

// Konsist Test
Konsist
    .scopeFromProject()
    .classes()
    .parents()
    .typeArguments
    .flatten()
    .assertTrue { 
        it.name == "String"  // true
    }
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.konsist.lemonappdev.com/veryfying-codebase/verify-generics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
