'Unique Set of an ordered key value pairs where the keys are only valid keys of another type
I'd like to create a type that takes a set (an array of key/value pairs with non-repeating keys).
// I have any given interface:
interface PersonRecord {
id: string
name: string
age: number
}
// A type for order by direction
type SortDirection = "asc" | "desc"
I'd like to have some type/interface combination that would allow me to do something like this:
valid objects:
const orderSort: SortType<PersonRecord> = {
0: { id: "asc" }
1: { age: "desc" }
}
const personNameSort: SortType<PersonRecord> = {
0: { name: "desc" }
}
invalid objects:
// only one key from PersonRecord at a time can be used in
// the values of the top level keys
const orderSort: SortType<PersonRecord> = {
0: { id: "asc", age: "desc" }
}
// The top level keys must be numbers starting at zero and iterating
// every natural number by having no skips
const orderSort: SortType<PersonRecord> = {
0: { id: "asc" }
2: { age: "desc" }
}
// "xxx" is not a valid value because its not "asc" or "desc"
const personNameSort: SortType<PersonRecord> = {
0: { name: "xxx" }
}
// test is not a key on PersonRecord
const personNameSort: SortType<PersonRecord> = {
0: { test: "xxx" }
}
// keys from PersonRecord can only be used once
const orderSort: SortType<PersonRecord> = {
0: { id: "asc" }
1: { id: "desc" }
}
Here's an attempt at getting part of this piece working.
type SortType<T> = { [K in keyof Partial<T>]: SortDirection }
Some alternative solutions I'll accept: An array of key/value (value restricted to "asc" or "desc") and the keys cannot be reused:
// this would work...
const sortOrder = [{name: "asc"},{age: "desc"}]
// ...but this wouldn't because age was already included in the array.
// If there's not a clean way of adding this restriction, then I can
// write code to prevent this restriction programmatically I'm sure.
const sortOrder = [{name: "asc"},{age: "desc"},{age: "asc"}]
EDIT: So to help with this solution, let me explain exactly what this would be used for.
I want to make a function like this:
// orderArgs could be an array also so maybe something like
// SortType<T>[] and each item in the array is just something like:
// [{someAttribute: "asc"},{anotherAttribute: "desc"}]
// and you can only have an array of ONE key/value pair.
const orderBy = (orderArgs: SortType<T>) => {
// a variable that orderBy has access to is called
// 'records' which is of type: T[]
return records.sort((last, next) => {
// to determine which value to return (-1, 0 or 1)
// I want to sort against the first item in orderArgs
// if they are not equal, return 1 or -1.
// However, if they are equal, go to the next item in
// orderArgs and try sort based on that.
// If you've gone through the whole list of orderArgs,
// then last and next are truly equal, so return 0 here.
}
}
EDIT 2: Here's a codesandbox proof of concept using @jcalz tips/help:
https://codesandbox.io/s/typed-data-storage-example-7n3kk4?file=/src/lib/useDataTable.ts
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
