Opaque Type: qué es, some y any en Swift

Autor: IT Sectr Publicado: 2026-06-18 Tiempo de lectura: 11 min

Opaque Type es un mecanismo de Swift que permite a una función devolver un valor de algún tipo sin revelar el tipo concreto al código llamante. La palabra clave some en el tipo de retorno es el ejemplo más conocido: some View en SwiftUI significa “la función devuelve algún tipo que cumple con View, pero cuál exactamente es un detalle de implementación.” Un opaque type preserva la identidad del tipo (a diferencia de un protocolo como tipo), lo que permite al compilador optimizar el código y garantiza la coherencia del tipo devuelto. Según Swift Book, 2025, los opaque types resuelven el problema de los protocolos con tipos asociados, permitiendo devolver valores de dichos protocolos desde funciones.

Puntos clave

  • Opaque Type — un tipo de retorno que oculta la implementación concreta del código llamante
  • some — la palabra clave para declarar un opaque type en posición de retorno
  • Identidad del tipo se preserva: el compilador conoce el tipo concreto, a diferencia de any
  • SwiftUI usa some View como la forma estándar de declarar body
  • Limitación: una función con some debe devolver el mismo tipo concreto desde todas las ramas

¿Qué es un Opaque Type en Swift?

Opaque Type es un tipo de retorno declarado con la palabra clave some que oculta la implementación concreta del código llamante. Quien llama solo sabe que el valor devuelto cumple con un determinado protocolo, pero no sabe exactamente qué tipo hay detrás de some. Mientras tanto, el compilador conoce el tipo exacto y lo utiliza para el despacho estático y la optimización.

El problema que resuelve Opaque Type

Antes de la introducción de los opaque types en Swift 5.1 (SE-0244), era imposible devolver un protocolo con tipos asociados desde una función sin un envoltorio de boxing. Por ejemplo, el protocolo Equatable tiene un tipo asociado, y una función no podía simplemente devolver Equatable — el compilador mostraba un error “el protocolo solo se puede usar como una restricción genérica.” Opaque type resolvió este problema.

swift
func makeInt() -> some Equatable {
    return 42
}

func makeString() -> some Equatable {
    return "Hello"
}

// El compilador sabe que makeInt devuelve Int
// makeInt() == makeString() — ❌ error, tipos diferentes

Ambas funciones devuelven some Equatable, pero los tipos concretos son diferentes: Int y String. Intentar compararlos con == provocará un error de compilación porque un opaque type garantiza que una llamada específica devuelve el mismo tipo, pero no entre diferentes funciones. Esto es una característica, no un error: opaque type preserva la identidad del tipo donde un protocolo como tipo (any Equatable) la pierde.

Opaque Type vs Generic: cuál es la diferencia

Generic y Opaque Type son dos caras de la misma moneda. Los genéricos permiten al código llamante elegir el tipo, mientras que opaque type permite a la función ocultar el tipo del código llamante. La diferencia está en la dirección del control.

CaracterísticaGeneric Opaque some
Quién elige el tipoCódigo llamanteFunción/método
Identidad del tipoPreservada (estable)Preservada (estable)
Número de ramas de retornoUna (mediante genérico)Mismo tipo en todas las ramas
UsoAlgoritmos, estructuras de datosSwiftUI, métodos de fábrica

Generic — elección externa

En una función genérica, el caller decide qué tipo usar. La función debe funcionar con cualquier T que satisfaga las restricciones. Para opaque type, el caller no conoce el tipo concreto — la implementación toma la decisión.

swift
// Generic: el caller elige el tipo
func identity<T>(_ value: T) -> T { value }
let x: Int = identity(42)

// Opaque: la función oculta el tipo
func makeSomeEquatable() -> some Equatable { 42 }
let y = makeSomeEquatable()

La elección entre generic y opaque type depende de la intención. Si el código llamante debe elegir el tipo, usa genéricos. Si la función debe ocultar detalles de implementación, usa some. SwiftUI eligió some View precisamente porque body debe ser flexible internamente pero estable externamente.

La palabra clave some y su uso

some es una palabra clave de Swift introducida en Swift 5.1 (SE-0244). Se usa en posición de retorno para declarar un opaque type, así como en parámetros (SE-0341) y propiedades. some garantiza que el tipo concreto es estable y conocido por el compilador pero oculto del código externo.

some en parámetros de función

A partir de Swift 5.7, some se puede usar no solo en posición de retorno sino también en parámetros. some Equatable en un parámetro significa “esta función acepta cualquier tipo Equatable, pero todas las llamadas dentro de un cuerpo específico ven el mismo tipo.”

swift
func areEqual(_ a: some Equatable, _ b: some Equatable) -> Bool {
    // a y b — tipos potencialmente diferentes, == no funcionará directamente
    return isEqual(a, b)
}

func isEqual<T: Equatable>(_ a: T, _ b: T) -> Bool {
    return a == b
}

Usar some en parámetros proporciona una sintaxis más concisa en comparación con . Es especialmente útil en protocolos y diseño orientado a protocolos, donde cada uso de un protocolo no requiere un parámetro genérico separado. El compilador internamente convierte los parámetros some en genéricos, por lo que el rendimiento es idéntico.

La palabra clave any y los tipos existenciales

any es una palabra clave de Swift 5.6+ para declarar explícitamente tipos existenciales (protocolo como tipo). A diferencia de some, any borra la identidad del tipo: el compilador no sabe qué tipo concreto se oculta detrás del protocolo. Esto proporciona flexibilidad (puedes almacenar diferentes tipos en un solo array), pero a costa del rendimiento.

some vs any: análisis comparativo

some — polimorfismo estático: el compilador conoce el tipo concreto, usa despacho directo y puede incluir código en línea. any — polimorfismo dinámico: se usa una tabla de métodos virtuales (contenedor existencial), lo que añade indirección.

swift
protocol Drawable {
    func draw()
}

// some: el tipo estático es conocido
func makeDrawable() -> some Drawable {
    return Circle() // Tipo de retorno único
}

// any: dinámico, puede almacenar diferentes tipos
var shapes: [any Drawable] = [Circle(), Square()]
shapes.append(Triangle())

La elección entre some y any es un compromiso entre rendimiento y flexibilidad. Some es más rápido pero se limita a una sola implementación. Any es más flexible (puedes mezclar tipos) pero más lento debido al despacho dinámico. En SwiftUI, body siempre usa some View porque el body de cada View es un tipo concreto.

Opaque Type en protocolos con tipos asociados

Opaque Type resuelve un problema fundamental de Swift: los protocolos con tipos asociados (PAT) no se pueden usar directamente como tipo. Una función no puede simplemente devolver Collection — el compilador requiere especificar Element. some Collection resuelve esto ocultando el tipo asociado.

Devolver PAT mediante some

Sin opaque type, devolver una Collection requeriría usar un tipo concreto (Array) o borrado de tipo (AnyCollection). some Collection proporciona un punto intermedio: el compilador conoce la implementación concreta, el código llamante no.

swift
func makeReversedCollection<T>(
    of array: [T]
) -> some Collection {
    return array.reversed()
}

let result = makeReversedCollection(of: [1, 2, 3])
// result — ReversedCollection>, hidden from caller
for item in result {
    print(item)
}

result se puede iterar, pero no se puede acceder directamente a las propiedades de ReversedCollection. Esto protege la encapsulación: si luego reemplazas reversed() por otro método con una implementación diferente, el código llamante no se romperá. Opaque type te da la libertad de cambiar la implementación sin cambiar la API.

Ejemplos prácticos de some View en SwiftUI

some View es el uso más famoso de opaque type. Cada View en SwiftUI declara body como some View. Esto significa que body devuelve algún tipo concreto de View, pero el desarrollador no necesita pensar exactamente qué es — TupleView, Group, ModifiedContent o cualquier otro tipo del framework.

Cómo usa SwiftUI some View

Sin opaque type, body tendría que devolver un tipo concreto, por ejemplo, ModifiedContent<Button<Text>, Padding>, lo cual no es práctico. some View oculta esta complejidad. El compilador infiere el tipo exacto de body automáticamente en tiempo de compilación.

swift
struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hola")
                .font(.title)
            Button("Tócame") {
                print("Tocado")
            }
        }
        .padding()
    }
}

El compilador infiere body como ModifiedContent<VStack<TupleView<(Text, Button<Text>)>>, Padding>. El desarrollador ve some View. Si cambias el diseño de VStack a HStack, el compilador reinferirá automáticamente el tipo — sin necesidad de ediciones manuales. Esta es la magia de opaque type: el desarrollador se enfoca en la lógica de la interfaz, no en los tipos de composición.

Preguntas frecuentes

¿Qué es un Opaque Type en Swift?

Opaque Type es un tipo declarado con la palabra clave some que oculta la implementación concreta del código llamante. El compilador conoce el tipo exacto, pero el desarrollador que usa la función solo ve el protocolo.

¿En qué se diferencia some de any en Swift?

some es un opaque type con identidad estática: el compilador conoce el tipo concreto. any es un tipo existencial con despacho dinámico: la identidad del tipo se borra. Some es más eficiente, any es más flexible.

¿Por qué SwiftUI usa some View?

some View oculta el complejo tipo concreto de body, que el compilador infiere automáticamente. Esto libera al desarrollador de tener que escribir el tipo exacto compuesto por envoltorios genéricos (VStack, Group, ModifiedContent).

¿Se puede usar some en parámetros de función?

, a partir de Swift 5.7. Some en parámetros es azúcar sintáctico sobre un parámetro genérico. Simplifica la declaración de funciones, especialmente al trabajar con protocolos donde cada parámetro some no requiere un separado.

¿Qué pasa si se devuelven diferentes tipos desde una función some?

El compilador mostrará un error: opaque type requiere que todas las ramas de retorno devuelvan el mismo tipo concreto. Esto es intencional para preservar la identidad del tipo. Si necesitas devolver diferentes tipos, usa any.

Resumen

  • Opaque Type — oculta el tipo concreto del valor de retorno preservando su identidad a nivel del compilador
  • La palabra clave some se usa para declarar un opaque type en posición de retorno y parámetros
  • Generic vs Opaque: el caller elige el tipo para generic, la implementación elige para opaque
  • any — tipo existencial con despacho dinámico, some — polimorfismo estático
  • SwiftUI some View — el caso de uso principal: oculta el tipo complejo de body del desarrollador
  • Opaque type resuelve el problema de devolver protocolos con tipos asociados (PAT) desde funciones

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también