#Element type of intersection of array/tuple

1 messages Β· Page 1 of 1 (latest)

jovial cobaltBOT
#
Aswin S Vijay#4646

Preview:```ts
type A = string[] & unknown[]
type A0 = A[0]
// ^?

type B = [string] & unknown[]
type B0 = B[0]
// ^?

type C = string[] & [unknown]
type C0 = C[0]
// ^?```

brave crypt
#

I'm curious why C0 is unknown, I would expect A0, B0 and C0 to be strings

cinder field
#

If you're looking for a rationale, this won't be it, but I believe it just prefers tuples over wide array types when resolving the access.

#

The same way this access resolves to unknown:

jovial cobaltBOT
#
angryzor#9490

Preview:```ts
type A = {
[key: string]: string
} & {
foo: unknown
}

type B = A["foo"]```

cinder field
#

You'll notice that

type D = string[] & [unknown] & [string]
type D0 = D[0]

does return string, it just prefers tuples since they're more explicit

#

Note that if you were to write the object example like this it wouldn't be accepted, precisely because these constructs are not entirely sound:

jovial cobaltBOT
#
angryzor#9490

Preview:```ts
type A = {
[key: string]: string
foo: unknown
}

type B = A["foo"]```

cinder field
#

If you try to use these kinds of intersections you even run into problems with assignment:

jovial cobaltBOT
#
angryzor#9490

Preview:```ts
type A = {
[key: string]: string
} & {
foo: unknown
}

type Afoo = A["foo"]
// ^?

const a: A = {
foo: null as unknown,
}

type B = string[] & [unknown]

type B0 = B[0]
// ^?

const b: B = [null as unknown]```

cinder field
#

You can even use intersections to override wide types like this with types that don't overlap at all, but you run into the same problems with assignment:

jovial cobaltBOT
#
angryzor#9490

Preview:```ts
type A = {
[key: string]: string
} & {
foo: number
}

type Afoo = A["foo"]
// ^?

const a: A = {
foo: 5,
}

type B = string[] & [number]

type B0 = B[0]
// ^?

const b: B = [6]```

cinder field
#

@brave crypt

brave crypt
#

Hmm I guess it does make some sense that TS gives preference to tuples

#

Looks like something similar applies to object types also

type X = {
    [k: string]: string
} & {
    foo: unknown;
};

type XFoo = X['foo']
//  ^? unknown
cinder field
#

?

#

That's what I mentioned above πŸ˜…

brave crypt
#

Oops, all those examples above confused my eyes πŸ˜Άβ€πŸŒ«οΈ

#

Thanks for the clarification πŸ‘

cinder field
#

Yw!

cinder field
#

!close