#allowing type hints for parameter object properties
36 messages · Page 1 of 1 (latest)
type Tr<T extends readonly Fn[]> = {
[K in keyof T]: T[K] extends (p: infer P) => infer R
? (p: Record<keyof P, string>) => R
: never;
};
function c<T extends readonly Fn[]>(fns: Tr<T>) {
return fns;
}
const ls = c([
//
({ name }) => `Hola ${name}`,
// ^?
// should be type hinted as string
({ age }) => `The age ${age}`,
]);
Preview:```ts
type Tr<T extends readonly Fn[]> = {
[K in keyof T]: T[K] extends (p: infer P) => infer R
? (p: Record<keyof P, string>) => R
: never
}
function c<T extends readonly Fn[]>(fns: Tr<T>) {
return fns
}
const ls = c([
//
({name}) => `Hola ${name
...```
@reef tulip
do you use nouncheckedindexedaccess?
What about simply?
type Fn = (arg: Record<string, string>) => string
function c(fns: Fn[]) {}
It would work without nUIA, which you don't have it turned on in the playground.
yes
the easiest solution would be to just use the big-ball-of-overloads approach that pipe uses
How would that work?
From my understanding, name and age are arbitrary strings so it needs to work with anything.
I don't think it's possible to do for arbitrary strings, since destructuring is implementation and does not affect types, so it's not possible to extract them.
You would have to change the API and repeat name/age somewhere in the types.
idk it kinda relates to #1214295571037290556
i think they have noUncheckedIndexedAccess off but i was personally curious about this
!ts
function c<K extends string>(fn: (arg: Record<K, string>) => string) {
return [fn];
}
const ls = c(
// ^? - function c<string>(fn: (arg: Record<string, string>) => string): ((arg: Record<string, string>) => string)[]
({ name }) => `Hola ${name}`,
// ^? - (parameter) name: string
);```
so probably a classic inference order issue
to get the param names the lambda needs to have started inference
I'm pretty sure { name } just doesn't participate in inference what so ever.
the function either infers before the lambdas start, or after the lambdas finish
that is what im also curious about. it does have the signature any
either way you cannot go from the lambdas to the outer function and back
i guess that's possible too
that was what i was going through mostly but ts has a lot of weird tricks
It makes sense for destructuring to be handled like:
({ name }) => {}
// same as
(_arg) => {
const { name } = _arg
}
So if that's the case, it's simply impossible to extract name at all.
!ts
const j = ({ name }) => `${name}`
// ^^^^
// Binding element 'name' implicitly has an 'any' type.
// ^? - const j: ({ name }: {
// name: any;
// }) => string
@glass stream the hint makes it look like _arg is inferred to be { name: any; }
so maybe i thought there was a way to get the keys
Hmm that does seem to be the case.
Preview:ts type Validate<T> = T extends never ? T : { [K in keyof T]: T[K] extends (arg: infer A) => string // ? (arg: Record<keyof A, string>) => string ? [(arg: Record<keyof A, string>) => string] : never } ...