Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intersection type with Record<string, never> does not allow property access

Tags:

typescript

I was a bit surprised to find out that:

type TypeA = Record<string, never> & { propA: string };

const a: TypeA = { // <- Type 'string' is not assignable to type 'never'
  propA: "lsjdf",
}

does not work in TypeScript. I'd love to replace Record<string, never> with something that means "empty object" but can't come up with a type that signifies an empty object.

I'd also love to understand why the above does not work.

like image 508
Xen_mar Avatar asked Apr 25 '26 05:04

Xen_mar


2 Answers

never means never.

Record<string, never> means "string type accessors can never have a value" (though { [Symbol()]: 'foobar' } is possible). Your TypeA is unusable because it creates a paradox: propA is a required string property that can never exist. The signature is correct, but there is no usable intersection between the types.

There are a few options for "empty":

  • Record<string, never> is an empty object in the sense that you can't add any string-type accessor properties to it (again, unless you use Symbol) so it will always be empty.
  • {} doesn't specify any properties, so any type may be assigned to it because every type satisfies all zero requirements (unless that type can never have accessible properties, i.e. undefined and null). However, while const foo: {} = 'bar' is possible, {} doesn't list any properties so there isn't really anything you can do with it without casting/annotations.
like image 69
Connor Low Avatar answered Apr 26 '26 18:04

Connor Low


u can use Union Types : |

type TypeA = Record<string, never> | { propA: string };

const a: TypeA = { 
  propA: "lsjdf",
}
like image 36
user21616651 Avatar answered Apr 26 '26 17:04

user21616651