What visibility and scoping rules apply to a top-level `typealias` declaration, and how does a `private typealias` differ from a `public` one when used across files in the same module?
answer
- public/internal/private (protected only for members)
- private = file-scoped name
- internal = module-scoped name
- Visibility hides the NAME, not the type
- No local (in-function) typealias
basics
~20 sA typealias lives at file or member level and can be public, internal, or private. A private one is visible only in its own file; a public one can be used anywhere it is imported. It is still just a synonym in all cases.
solid answer
~50 sA top-level `typealias` is a **declaration** with normal Kotlin visibility modifiers: `public` (default), `internal`, and `private`. `private` scopes the alias to **its own file**; `internal` to the **module**; `public` makes it visible to any consumer that imports it. Crucially, **visibility only governs where the *name* can be referenced** — it never changes the typing rules, because the alias is still a compile-time synonym for the underlying type. A value flowing through a `private typealias` is the *same* underlying type as one written with the full type elsewhere, so callers who can't see the alias can still pass the equivalent expanded type. Aliases obey package/import rules like other top-level declarations: you `import pkg.MyAlias` to use it in another file. They can be declared at top level or as members (where member visibility and the enclosing scope apply). They cannot be local (inside a function body).
go deeper
Knows aliases can be public/private and live at file scope.
Maps modifiers to scope (file/module) and knows no local aliases exist.
Explains that visibility hides the name only, and that returning a private alias still exposes the underlying type publicly.
Advises on API surface design — keeping alias vocabulary internal so it doesn't become an unstable part of the public contract.
## Where a typealias can live - **Top level** of a file (most common). - **Member** position (inside a class/object/interface body) — subject to the enclosing scope and member visibility. - **Not** inside a function body — local typealiases are not allowed. ## Visibility modifiers A `typealias` accepts the standard modifiers: ```kotlin public typealias PublicCache = Map<String, Int> // default; visible to importers internal typealias ModuleCache = Map<String, Int> // visible within the module private typealias FileCache = Map<String, Int> // visible only in THIS file ``` - **`public`** (default): usable anywhere the file/package is imported. - **`internal`**: usable across the **same module** (Gradle/Maven module), invisible outside it. - **`private`** at top level: usable **only within the declaring file**. - **`protected`** is allowed only for *member* typealiases (not top-level), like other member declarations. ## Crucial point: visibility names, not types Visibility controls **who can write the alias name** — it does **not** create a hidden or distinct type. Since the alias is a synonym, code that can't see `FileCache` can still produce/consume the *underlying* `Map<String, Int>`: ```kotlin // File A private typealias FileCache = Map<String, Int> fun make(): FileCache = mapOf("a" to 1) // exposes Map<String,Int> in its public signature // File B (cannot name FileCache) val c: Map<String, Int> = make() // fine: same underlying type ``` So a `private typealias` does **not** hide the type from other files; it only prevents them from using the **short name**. Public API signatures expand the alias to its underlying type in the compiled/exposed form. ## Import & package rules A top-level `typealias` is referenced across files via import, like any top-level symbol: ```kotlin import com.acme.PublicCache ``` ## Practical guidance - Use `private`/`internal` for aliases that are **implementation-local readability helpers** so they don't leak as part of your stable public vocabulary. - Remember exposing a function that *returns* a private alias still exposes the **underlying** type publicly — the alias name just won't appear to outside callers. ## Summary Visibility on a typealias is ordinary Kotlin visibility applied to a **name**; the aliased type and its assignability are unaffected.
- If a public function returns a `private typealias`, can outside callers still use the result?Yes. They just can't name the alias; the signature exposes the underlying type, which they can use directly.
- Can a typealias be `protected`?Only as a member typealias inside a class hierarchy; top-level typealiases can't be protected.
saying these in an interview costs you the question
- Thinking private typealias hides the underlying type from other files
- Believing visibility changes assignability/type identity
- Saying typealias can be declared inside a function
- Claiming internal means file-scoped (it is module-scoped)
- Assuming an alias must be imported to use its underlying type