> For the complete documentation index, see [llms.txt](https://docs.konsist.lemonappdev.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.konsist.lemonappdev.com/features/declaration-references.md).

# Declaration References

Declaration reference represents a link between codebase declarations. Konsist allows precise verification of properties of the linked type. This type can be used in function or property declaration or child/parent class or interface. For example:

1\. Verify if all types of function parameters are interfaces:

```kotlin
Konsist
    .scopeFromProject()
    .functions()
    .parameters
    .types
    .assertTrue {
        it.sourceDeclaration?.isInterface
    }
```

2\. Access properties of parents (parent classes and parent interfaces). Below snippet checks if all parent interfaces have `internal` modifier:

```kotlin
fun `all parent interfaces are internal`() {
    Konsist
        .scopeFromProject()
        .classes()
        .parentInterfaces()
        .assertTrue {
            it.sourceDeclaration?.asInterfaceDeclaration()?.hasInternalModifier
        }
}
```

3\. Access properties of children (child classes and child interfaces). Below snippet checks if all interfaces have children that reside in `..somepackage..` package:

```kotlin
Konsist
    .scopeFromProject()
    .interfaces()
    .assertTrue {
        it.hasAllChildren(indirectChildren = true) { child -> 
            child.resideInPackage("..somepackage..") 
        }
    }
```

## Type Representation

Kotlin types can be defined in multiple ways. Consider `foo` property with `Foo` type:

```kotlin
val foo: Foo
```

The `Foo` type can be defined by:

* class
* interface
* object
* type alias
* import alias
* kotlin types (Kotlin basic type or Kotlin collections type)
* function type
* external library (type defined outside project codebase) represents declaration which is not defined in the project

The `Foo` type can be represented by one of `KoXDeclaration` classes:

<table><thead><tr><th width="464">Source</th><th width="282">Declaration</th></tr></thead><tbody><tr><td><a data-mention href="#type-represented-by-class">#type-represented-by-class</a></td><td><code>KoClassDeclaration</code></td></tr><tr><td><a data-mention href="#type-represented-by-interface">#type-represented-by-interface</a></td><td><code>KoInterfaceDeclaration</code></td></tr><tr><td><a data-mention href="#type-represented-by-object">#type-represented-by-object</a></td><td><code>KoObjectDeclaration</code></td></tr><tr><td><a data-mention href="#type-represented-by-type-alias">#type-represented-by-type-alias</a></td><td><code>KoTypeAliasDeclaration</code></td></tr><tr><td><a data-mention href="#type-represented-by-import-alias">#type-represented-by-import-alias</a></td><td><code>KoImportAliasDeclaration</code></td></tr><tr><td><a data-mention href="#type-represented-by-kotlin-type">#type-represented-by-kotlin-type</a></td><td><code>KoKotlinTypeDeclaration</code></td></tr><tr><td><a data-mention href="#type-represented-function-type">#type-represented-function-type</a></td><td><code>KoFunctionDeclaration</code></td></tr><tr><td><a data-mention href="#type-represented-by-external-type">#type-represented-by-external-type</a></td><td><code>KoExternalDeclaration</code></td></tr></tbody></table>

Each of these types possesses a largely distinct set of characteristics; for instance, classes and interfaces can include annotations, whereas import aliases cannot.

To access properties of the specific declaration type, the declaration must be cast to a more specific type (from generic `KoTypeDeclaration`). Example below assumes that `Foo` is represented by the `Foo` class:

```kotlin
Konsist
    .scopeFromProject()
    .properties()    
    .types
    .assertTrue { koTypeDeclaration ->
        val koClass = koTypeDeclaration.sourceDeclaration as KoClassDeclaration

        koClass.hasAllAnnotations {
            it.representsTypeOf<String>()
        }
    }
```

To facilitate testing Konsist API provides a set of dedicated casting extensions. The above code can be simplified:

```kotlin
Konsist
    .scopeFromProject()
    .properties()
    .types
    .assertTrue { koTypeDeclaration ->
        koTypeDeclaration
        .sourceDeclaration
        ?.asClassDeclaration()
        ?.hasAllAnnotations {
            it.representsTypeOf<String>()
        }
    }
```

Here is the list of all casting extensions (available on `sourceDeclaration`):

<table data-full-width="true"><thead><tr><th>Source</th><th width="273">Declaration</th><th>Cast Extension</th><th>Type Check Extension</th></tr></thead><tbody><tr><td><a data-mention href="#type-represented-by-class">#type-represented-by-class</a></td><td><code>KoClassDeclaration</code></td><td><code>asClassDeclaration()</code></td><td><code>isClass</code></td></tr><tr><td><a data-mention href="#type-represented-by-interface">#type-represented-by-interface</a></td><td><code>KoInterfaceDeclaration</code></td><td><code>asInterfaceDeclaration()</code></td><td><code>isInterface</code></td></tr><tr><td><a data-mention href="#type-represented-by-object">#type-represented-by-object</a></td><td><code>KoObjectDeclaration</code></td><td><code>asObjectDeclaration()</code></td><td><code>isObject</code></td></tr><tr><td><a data-mention href="#type-represented-by-type-alias">#type-represented-by-type-alias</a></td><td><code>KoTypeAliasDeclaration</code></td><td><code>asTypeAliasDeclaration()</code></td><td><code>isTypeAlias</code></td></tr><tr><td><a data-mention href="#type-represented-by-import-alias">#type-represented-by-import-alias</a></td><td><code>KoImportAliasDeclaration</code></td><td><code>asImportAliasDeclaration()</code></td><td><code>isImportAlias</code></td></tr><tr><td><a data-mention href="#type-represented-by-kotlin-type">#type-represented-by-kotlin-type</a></td><td><code>KoKotlinTypeDeclaration</code></td><td><code>asKotlinTypeDeclaration()</code></td><td><code>isKotlinType</code></td></tr><tr><td><a data-mention href="#type-represented-by-external-type">#type-represented-by-external-type</a></td><td><code>KoExternalDeclaration</code></td><td><code>asExternalDeclaration()</code></td><td><code>isExternal</code></td></tr></tbody></table>

### Type Represented By Class

Source code:

```kotlin
internal class Foo
```

Usage:

```kotlin
val foo: Foo? = null
```

Konsist test:

```kotlin
scope
    .properties()
    .types
    .assertTrue {
        it.sourceDeclaration?.asClassDeclaration()?.hasInternalModifier
    }
```

### Type Represented By Interface

Source code:

```kotlin
internal interface Foo
```

Usage:

```kotlin
val foo: Foo? = null
```

Konsist test:

```kotlin
scope
    .properties()
    .types
    .assertTrue {
        it.sourceDeclaration?.asInterfaceDeclaration()?.hasInternalModifier
    }
```

### Type Represented By Object

This scenario is uncommon, but still possible.

Source code:

```kotlin
internal object Foo
```

Usage:

```kotlin
val foo: Foo? = null
```

Konsist test:

```kotlin
scope
    .properties()
    .types
    .assertTrue {
        it.sourceDeclaration?.asObjectDeclaration()?.hasInternalModifier
    }
```

### Type Represented By Type Alias

Source code:

```kotlin
internal interface Foo
```

Usage:

```kotlin
typealias MyFoo = Foo
val foo: MyFoo? = null
```

Konsist test:

```kotlin
scope
    .properties()
    .types
    .assertTrue {
        it
            .sourceDeclaration
            ?.asTypeAliasDeclaration()
            ?.type
            ?.sourceDeclaration
            ?.asInterfaceDeclaration()
            ?.hasInternalModifier
    }
```

### Type Represented By Import Alias

Source code:

```kotlin
internal interface Foo
```

Usage:

```kotlin
import com.app.Foo as MyFoo

val foo: MyFoo? = null
```

Konsist test:

```kotlin
scope
    .properties()
    .types
    .assertTrue {
        it
            .sourceDeclaration
            ?.asImportAliasDeclaration()
            ?.sourceDeclaration
            ?.asInterfaceDeclaration()
            ?.hasInternalModifier
    }
```

### Type Represented By Kotlin Type

Source code:

```kotlin
// Kotlin internal source code for String
```

Usage:

```kotlin
val foo: String? = null
```

Konsist test:

<pre class="language-kotlin"><code class="lang-kotlin">scope
    .properties()
    .types
    .assertTrue {
<strong>        it.sourceDeclaration?.asKotlinTypeDeclaration()?.name == "String"
</strong>    }
</code></pre>

### Type Represented Function Type

Source code:

```kotlin
// Kotlin internal source code
```

Usage:

```kotlin
val foo: (() -> Unit)? = null
```

Konsist test:

<pre class="language-kotlin"><code class="lang-kotlin">scope
    .properties()
    .types
    .assertTrue {
<strong>        it
</strong><strong>            .parameters
</strong>            ?.isEmpty()
    }
</code></pre>

### Type Represented By External Type

External type represents the type defined outside of the project codebase, usually by external library. Konsist is not able to parse this type, so type information is limited (Konsist is not able to parse the compiled file).

For example:

```kotlin
class MyViewModel : ViewModel()
```

The Android `ViewModel` class is provided by `androidx.lifecycle:lifecycle-viewmodel-ktx` dependency, so Konsist has limited information.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.konsist.lemonappdev.com/features/declaration-references.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
