-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Call-site polymorphism for lensIndex
and lensProp
#187
Comments
Just spotted that lensIndex(n: number): {
<U>(arr: ReadonlyArray<U>): U;
<U>(newVal: U, arr: ReadonlyArray<U>): ReadonlyArray<U>;
}; It'd be cool if the type checking there could have been deferred similarly to |
Hm. Trying these in the console at the Ramda docs seems to be given something that matches with neither of these: R.lensIndex(0)
// function
R.lensIndex(0)([1,2,3])
// function
R.lensIndex(0)('a', [1,2,3])
// function Seems the getter / setter methods are somehow wrapped in that
Hm. The primary obstacle there would be export type NumberToString = { /*[i: number]: string;*/ 0:'0',1:'1',2:'2',3:'3',4:'4',5:'5'};
export type StringToNumber = { /*[k: string]: number;*/ 0:0,1:1,2:2,3:3,4:4,5:5};
// ^ adding `[k: string]: number;` gives a fallback but causes a bunch of `Type 'StringToNumber[I]' cannot be used to index type ...`
declare function lensProp<TProp extends string>(prop: TProp): {
<U extends {[T in TProp]: any; }>(obj: U): U[TProp];
};
const obj: { a: 1, b: 2 } = { a: 1, b: 2 };
let x = lensProp('a')(obj);
// ^ 1
let y = lensProp('c')(obj);
// ^ error
let z = lensProp(null! as string)(obj);
// ^ any
declare function lensIndex<
TProp extends number,
TString extends string = NumberToString[StringToNumber[TProp]]
>(prop: TProp): {
<U extends {[T in TString]: any; }>(obj: U): U[TString];
};
const arr: [1, 2] = [1, 2];
let a = lensIndex(0)(arr);
// ^ 1
let b = lensIndex(123)(arr);
// ^ error
let c = lensIndex(null! as number)(arr);
// ^ `any` with index, `1 | 2` without
type d = NumberToString[StringToNumber[number]];
// ^ from `lensIndex`, but errors when separated... wth? I'll admit I'm confused by the result here, but yeah, progress. I guess since this doesn't have other dependencies we could already use it too, unlike much else. Longer versions here; I'm on the fence over those indices now, and don't yet know a workaround to solve the issue with adding one to |
@tycho01 I actually don't know how well the types actually align with the runtime Ramda library; I didn't try it out at runtime. I was just describing how you can avoid losing type information with the type signatures you have now, which are: interface ManualLens<U> {
<T extends Struct<any>>(obj: T): U; // get
set<T extends Struct<any>>(v: U, obj: T): T;
// <T extends Struct<any>>map(fn: (v: U) => U, obj: T): T
}
///...
lensIndex<T>(n: number): ManualLens<T> This still demands you do If Ramda returns some other kind of thing (functor apparently), we need to repeat ourselves here and make a special cased |
Thanks, yeah,
R.view(R.lensIndex(10), 'foo')
// -> "" 😅
Yeah, something like that. |
lensIndex
should be defined as follows:lensProp
should be defined as follows:There's probably some mindbending recursive interface stuff that could be done to make
lensPath("foo")("bar")("baz")
be typed as<T extends { foo: { bar: { baz } } }>(x: T) => T["foo"]["bar"]["baz"]
, but my type tetris is too weak.The text was updated successfully, but these errors were encountered: