Skip to content

Conversation

@Nemo108
Copy link
Contributor

  • remove unnecessary constraint from propEq value: the function should receive any type values of object, no matter what parameter it received;
  • add additional types to use with placeholder

@Harris-Miller
Copy link
Collaborator

@Nemo108 I finally got around to re-checking and merging #71. Rebase this one for me and I'll recheck it

@Nemo108Nemo108force-pushed the @nemo108/propEq-fix-preview branch from 6f999a0 to f734c70CompareJanuary 21, 2024 09:47
@Nemo108
Copy link
ContributorAuthor

@Harris-Miller done

str: string;
num: number;
int: number;
numLike: number| `${number}`;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

${number} is a neat trick! Allows strings that only contain number characters, very cool

};
exportfunctionpropEq<KextendskeyofU,constU>(__: Placeholder,name: K,obj: U): (val: WidenLiterals<U[K]>)=>boolean;
exportfunctionpropEq<KextendskeyofU,constU>(val: WidenLiterals<U[K]>,__: Placeholder,obj: U): (name: K)=>boolean;
exportfunctionpropEq<KextendskeyofU,constU>(val: WidenLiterals<U[K]>,name: K,obj: U): boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to WidenLiterals<U[K]> here. When we know the type of U, we want to constrain val to U[K]

typeObj={prop: 'foo'|'bar'};// we want to disallow strings other than `'foo'` and `'bar'` here for `val`propEq('biz','prop',obj);

WidenLiterals<U[K]> is needed for the curried versions before of how typescript infers types

constdoesEqualFoo=propEq('foo','prop');// without `WidenLiterals<U[K]>`, the type would be `Record<'prop', 'foo'>`, but obj is `{prop: 'foo' | 'bar' }`, which is too wide for just `'foo'`.// with `WidenLiterals<U[K]>`, the type would be `Record<'prop', string>`, so `obj` is alloweddoesEqualFoo(obj)

Typescript doesn't support currying like this that well in general, but we do the best we can with what we have

};
exportfunctionpropEq<T,KextendsPropertyKey>(val: T,name: K): (obj: Record<K,T>)=>boolean;
exportfunctionpropEq<KextendskeyofU,U>(val: U[K],name: K,obj: U): boolean;
exportfunctionpropEq<KextendsPropertyKey>(__: Placeholder,name: K): Kextendsnumber ? {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of the ternary, we do 2 overloads

exportfunctionpropEq<Kextendsnumber>(__: Placeholder,name: K): {// ...}exportfunctionpropEq<KextendsExclude<PropertyKey,number>>(__: Placeholder,name: K): {// ...}

? (array: Array<WidenLiterals<V>>)=>boolean
: (obj: Record<K,WidenLiterals<V>>)=>boolean;
<constU>(__: Placeholder,obj: U): (name: keyofU)=>boolean;
<KextendskeyofU,constU>(name: K,obj: U): boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think const U in needed here. U should be find.

You need to constrain U and K here though. If typeof U[K] as well. Turns out you don't need WidenLiterals here at all, in fact, it would actually break if U[K] was string | number but you passed a string to val: V.

See here: https://tsplay.dev/m3KbAm

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

V extends U[K] ? U : never creates too strict constraint: it fires an error on any string I pass there

https://tsplay.dev/wOXozN

But I think I came up with a better solution

@Nemo108Nemo108force-pushed the @nemo108/propEq-fix-preview branch from f734c70 to 895debcCompareFebruary 2, 2024 22:56
* remove unnecessary constraint from propEq value: the function should receive any type values of object, no matter what parameter it received; * add additional types to use with placeholder
@Nemo108Nemo108force-pushed the @nemo108/propEq-fix-preview branch from 895debc to 1e22d85CompareFebruary 2, 2024 23:00
@Harris-Miller
Copy link
Collaborator

@Nemo108 I'm having to revert the other propEq we collaborated on together: #74 (see: #99)

This MR is actually of of develop before that merge, so after the revert happens there should be no more merge conflict.

The additions made to #74 solved a different problem about propEq. I pretty sure the changes in this MR are find to merge without those changes. I'm also pretty sure that the specific change of #74 that broke it (argument possibly being never) not present in these changes, so we shouldn't have that problem again

Comment on lines +1 to +2
import{Placeholder}from'ramda';
import{WidenLiterals}from'../util/tools';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import{Placeholder}from'ramda';
import{WidenLiterals}from'../util/tools';
import{Placeholder,WidenLiterals}from'../util/tools';


exportfunctionpropEq(__: Placeholder): never;
exportfunctionpropEq<constV>(val: V): {
<Kextendsnumber>(name: K): <Uextendsany[]>(array: VextendsU[K] ? V[] : never)=>boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah crap, I missed this when I left that other comment about this MR not being a problem

array: V extends U[K] ? V[] : never 

This is the thing we can't have. It breaks combining with other functions, egR.filter(R.propEq('type', 'something')). The predicate type signatures don't match because of the : never

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Nemo108@Harris-Miller