arktype icon indicating copy to clipboard operation
arktype copied to clipboard

Mapped types

Open ssalbdivad opened this issue 2 years ago • 2 comments

I created the following props rule type to support intersections/unions and eventually checking types whose values are dependent on associated keys. Some parts of this may end up being out of date, but would be a good basis to start with.

const mappedKeyRegex = /^\[.*\]$/

const isMappedKey = (propKey: string) => mappedKeyRegex.test(propKey)

export type TraversalMappedPropsRule = [
    mappedEntries: readonly TraversalMappedPropEntry[],
    namedProps?: {
        readonly required?: TraversalPropSet
        readonly optional?: TraversalPropSet
    }
]

export type TraversalMappedPropEntry = [
    ifKeySatisfies: TraversalNode,
    thenCheckValueAgainst: TraversalNode | ((key: string) => TraversalNode)
]

export type TraversalPropSet = { readonly [propKey in string]: TraversalNode }

ssalbdivad avatar Jan 23 '23 19:01 ssalbdivad

Here's an example of how the syntax might be used (thanks @Dimava):

const actualRecordScope = scope({
   index: '1 | 3 | 5 | 7',
   record: {
      '[K in index]': 'index'
   }
})

ssalbdivad avatar May 10 '23 18:05 ssalbdivad

I have a dirty proposal of clear difference between finite and infinite records:

const actualRecordScope = scope({
   finiteIndex: '1 | 3 | 5 | 7',
   finiteRecord: {
      '[K of finiteIndex]': 'index' // OF for every-key-of-type, requires type to be able to list all its values
   },
   infiniteIndex: /^\w+$/,
   infiniteRecord: {
      '[K in infiniteIndex]': 'index' // IN
   },
})

Dimava avatar May 11 '23 08:05 Dimava