#Conditional type troubles

34 messages · Page 1 of 1 (latest)

loud terrace
loud terrace
twin meteor
#

i'd guess it's due to the conditional, i can't really explain past that though

#

you could rewrite Foo to avoid the conditional though

hexed moonBOT
#
that_guy977#0

Preview:```ts
type Foo<K, T> = T[K & keyof T]
// type Foo<K, T> = T[Extract<K, keyof T>]; // this doesn't work either, maybe because Extract uses a conditional

function test1<K, T>(foo: Foo<K, T>) {}

function test2<K extends keyof T, T>(foo: T[K]) {
test1(foo)
...```

steady raven
#

This can be super wrong, but I got a suggestion in my editor:

type Foo<K, T> = K extends keyof T ? T[K] : never;

function test1<K, T>(foo: Foo<K, T>) { }

function test2<K extends keyof T, T>(
  foo: T extends Record<K, any> ? T[K] : never
) {
    test1(foo);
}

This makes sure that K is indeed a key of T at least

twin meteor
#

it was already made sure by the bound keyof T

#

surprising that that works...

#

hmm i think maybe the lack of infer targets is also an issue

steady raven
#

I think so yeah.

#

The error kinda points towards that.

#

mainly this: 'T[string] | T[number] | T[symbol]' is not assignable to type 'Foo<K, T>'

twin meteor
hexed moonBOT
#
that_guy977#0

Preview:ts ... function test2<K extends keyof T, T>(foo: T, bar: K) { test1(foo[bar]) } ...

twin meteor
#

i have no idea what's going on there

steady raven
#

If you T extends Record, it works fine

#

Your last one at least.

twin meteor
#

(use plain ts playground links so they get embedded)

steady raven
#

Ah

hexed moonBOT
#
mjuksel#0

Preview:```ts
type Foo<K, T> = K extends keyof T ? T[K] : never

function test1<K, T>(foo: Foo<K, T>) {}

function test2<
K extends keyof T,
T extends Record<any, any>

(foo: T, bar: K) {
test1(foo[bar])
}```

steady raven
#

Didn know that 🙂 wups

twin meteor
#

it still errors with extends object

steady raven
#

Yep, I noticed

twin meteor
#

but yeah that infers correctly too

twin meteor
hexed moonBOT
#
that_guy977#0

Preview:```ts
type Foo<K, T> = K extends keyof T ? T[K] : never

function test1<K, T>(foo: Foo<K, T>) {
return foo
}

function test2<K extends keyof T, T>(
foo: T extends Record<K, any> ? T[K] : never
) {
return test1(foo)
}

test2(() => "")
test2<"toString", string>(() => "")
...```

twin meteor
#

these all seem to return never

steady raven
#

yeah until you give type parameters

#
test2<'a', { a: string }>('hello')
#

oh wait still never as return

#

lol I changed the T extends Record... back to T[K], the return type is correct, but now the foo arg on the inner function is wrong again

hexed moonBOT
#
mjuksel#0

Preview:```ts
type Foo<K, T> = K extends keyof T ? T[K] : never

function test1<K, T>(foo: Foo<K, T>) {
return foo
}

function test2<K extends keyof T, T>(foo: T[K]) {
return test1(foo)
}

test2<"toString", string>(() => "")```