#Record with Value as Generic Type

12 messages · Page 1 of 1 (latest)

muted star
#

Hi, I'm trying to define a type definition that is conditional based on the value. This is what I mean:

(added playground)

ExportType can be a plain string, or if it's an array, the second element must be an object of type Import, but if the first element is default, the as prop is required.

austere mist
#

you can't make it a generic, since typescript doesn't know how to split the string type into 'default' and not 'default'

#

firstly because string isn't a union, secondly because negated types (not T) don't exist

#

and also of course, like with almost every other type system, you can't have multiple different instantiations of a generic in the same array

#

you can have Foo<T>[], you can have Foo<U>[], but you can't have [Foo<T>, Foo<U>] by doing Foo<any>[] or whatever

#

you can validate types though

#

!:cif

pulsar bladeBOT
#
Gerrit0#7591
`!gerrit0:cif`:

If you want to both validate that a variable matches a specific type and also let TypeScript narrow the variable if possible, a constrained identity function is usually the best way to do this:

interface Foo {
  foo: string | number;
}
function createFoo<T extends Foo>(x: T) { return x }

const foo = createFoo({ foo: 123 })
//    ^? const foo: { foo: number }
#
n_n#2622

Preview:```ts
...
type ExportType =
| string
| [string, Partial<Import>]
| ["default", Partial<Import> & Pick<Import, "as">]

const e: Record<Package, ExportType[]> = {
ofetch: ["ofetch"], // should not be required
// h3: [], // not yet implemented
"is-https": [["default", {as: "isHTTPS"}]],
defu: [
"defu",
"createDefu",
"defuFn",
"defuArrayFn",
],
destr: [["default", {as: "destr"}]],
"items-promise": ["series", "parallel"],
"should-fail": [
[
"default",
{
/* no .as, so it should fail */
},
],
],
}```

austere mist
#

this almost works...

#

but not quite since default overlaps

austere mist