typescript - Definiția tipurilor de intersecție atribuibile


Vedem definiția pentru intersecția tipurilor în

https://github.com/microsoft/TypeScript/pull/3622

A & B poate fi atribuit lui X dacă A poate fi atribuit lui X sau B poate fi atribuit lui X.

type A = {x:1}
type B = {y:1}

type I = A & B 

declare function f(t:{x:1;y:1}):void

let i:I = {} as I
let a:A = {} as A
let b:B = {} as B

f(a) // error
f(b) // error
f(i) // ok

După cum putem vedea, A {x:1} și B {y:1} nu pot fi atribuite lui X {x:1;y:1}, dar I poate fi atribuit lui X.

Este definitia greșită? Sau am ratat ceva?

Răspuns #1

Definiția este în regulă.


"X poate fi atribuit lui Y" este o altă modalitate de a spune "X este un subtip al Y". Așadar, poți reformula definiția astfel:

A & B este un subtip de X dacă A este un subtip de X sau B este un subtip de X

De exemplu, dacă ai o valoare de tip Cat & Warm, o poți pune într-o variabilă de tip Cat, într-o variabilă de tip Warm și într-o variabilă de tip Animal (pentru că Cat este un subtip al Animal). Cu alte cuvinte, Cat & Warm este un subtip al Cat, un subtip al Warm și un subtip al Animal.


Așa cum putem vedea, A {x:1} și B {y:1} nu pot fi atribuite lui X {x:1;y:1}, dar I poate fi atribuit lui X.

Corect, A nu poate fi atribuit lui A & B, și B nu poate fi atribuit lui A & B. Definiția susține că A & B poate fi atribuit lui A și A & B poate fi atribuit lui B.

"X poate fi atribuit lui Y" înseamnă că dacă ai o variabilă x de tip X, aceasta este legală:

const y: Y = x

Deci asta este legal:

const a: A = a_and_b
const b: B = a_and_b

dar acesta nu este:

const ab: A & B = a
const ab: A & B = b

Exemplu (link către teren de joacă):

type A = {x: 1} | {z: 42}
type B = {x: 1}
type C = {y: 2}

function f(bc: B & C) {
    const b: B = bc  // OK, because B & C is assignable to B
    const c: C = bc  // OK, because B & C is assignable to C
    const a: A = bc  // OK: B is assignable to A, so B & C is assignable to A
}

function g(b: B) {
    const bc: B & C = b  // not OK: doesn't work the other way around
}

În exemplul tău, faci lucrul din function g când apelezi funcțiile f cu a și b ca argumente. Aceasta va cauza o eroare deoarece A nu poate fi atribuit lui A & B și B nu poate fi atribuit lui A & B.