Skip to content
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

Proposal: DeepRecord #103

Closed
GentileFulvio opened this issue Apr 29, 2020 · 2 comments · Fixed by #321
Closed

Proposal: DeepRecord #103

GentileFulvio opened this issue Apr 29, 2020 · 2 comments · Fixed by #321
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@GentileFulvio
Copy link
Contributor

GentileFulvio commented Apr 29, 2020

A while back while working on a project we needed a generic function to slice all strings of the provided object.

const stringSlicer = <T, U> (data: T, checker: U): T => {};

We wanted the U type the have the same type as the first argument but it had to flatten all the arrays.
So if T was of type

interface T {
	name: string;
	items: {
 		id: string
	}[]
}

U had to be of type

interface U {
	name: number;
	items: {
		id: number;
	}
}

With interface U defining the length of each string. But it shouldn't provide an array for items

proposal

export type DeepRecord<K, T> = {
	[P in keyof K]:
		Exclude<K[P], undefined> extends Array<infer E> ? DeepRecord<E, T> :
		Exclude<K[P], undefined> extends object ? DeepRecord<K[P], T> :
		T;
};

This way we can write the function as following

const stringSlicer = <T> (data: T, checker: DeepRecord<T, number>): T => {};
@sindresorhus
Copy link
Owner

We have deep-versions of other built-in types, so I don't mind having this added. The name should be RecordDeep though, to fit with our existing naming scheme.

For anyone wanting to work on this, please read https://github.com/sindresorhus/type-fest/blob/master/.github/contributing.md thoroughly.

@sindresorhus sindresorhus added enhancement New feature or request help wanted Extra attention is needed labels May 2, 2020
@kainiedziela
Copy link
Contributor

I'd be glad to take this one, however there is an issue I need some clarification on: this doesn't really replicate Record<K, T> functionality. In fact I'm not sure such a functionality could be replicated on a nested object. How would that look like?

const stringsToConvertToProps = {
    keyOne: 'key1',
    foo: {
        keyTwo: 'key2'
    }
}

Becomes what exactly after going through RecordDeep<stringsToConvertToProps, string>?

type Converted = { key1: string, key2: string }

or

type Converted = { key1: string, foo: { key2: string } }

?

Record<K, T> is pretty straightforward, this would be anything but, especially given the naming. I quite like what @GentileFulvio tries to achieve here, but it's not really in the scope of Record. What's being done here is coercing all of an object props to a given type, unless that prop has a type of object, then we're nesting deeper. Cool. But we need a different name for that.

@sindresorhus thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants