3

How can I define a type which either has block of extra properties (on top of isLocked) or does not have them at all? Partial guarantees all extra properties are optional. I want all of them to be required or not exist at all.

type AccountMetadata = {
  roles: string[];
  name: string;
}

type Account = {
  isLocked: boolean;
} & (AccountMetadata | {})

type Account = {
  isLocked: boolean;
} & (AccountMetadata | never)

Expected result

{ isLocked: boolean; roles: string[]; name: string } | { isLocked: boolean }
LazioTibijczyk
  • 1,701
  • 21
  • 48
  • 1
    [ts playground](https://www.typescriptlang.org/play?#code/C4TwDgpgBAggxnA9gVwHbALIWAQwCY65QC8UA3gLABQUUATogDYQDOAXFC8HQJaoDmAbQC6Abmq1UOALYQOXXgPFUAvtVCRYCFOgAyiOAGsIeEuQlQeLfUZMcARoiYQcqZWqobo8JGmBmACh8dYBtjUwAyLV90LFwCXABKKAAfaJCwk2VqJFQuKBxtPw5gvzNKGktrA3CObmQIABoLKVkOAHIcezh25tUgA) showing my solution but it doesn't complain about missing properties – Robert Rendell Mar 23 '23 at 12:28
  • 1
    Does this answer your question? [Does Typescript support mutually exclusive types?](https://stackoverflow.com/questions/42123407/does-typescript-support-mutually-exclusive-types) – Cuzy Mar 23 '23 at 12:33
  • 1
    Is it possible that what you really want is the object to be either `{ isLocked: false; }` or `{ isLocked: true; roles: string[]; name: string; }`? I.e. `isLocked` can act as type discriminator? – Nikos Paraskevopoulos Mar 23 '23 at 13:39
  • Is your expected result *really* the expected result? The type `{isLocked: boolean}` does not prohibit extra properties. Please try to provide a [mre] that shows how you'd like the type to actually behave (like, values which should and should not be valid `Account`s). – jcalz Mar 23 '23 at 13:57

1 Answers1

0

Not exactly a type extension, but you could do something like this:

type AccountMetadata = {
  roles: string[];
  name: string;
}

type Account<T extends AccountMetadata> = {
  isLocked: boolean;
  metadata?: T
}

var example1: Account<AccountMetadata> = {isLocked : true}; // ok
var example2: Account<AccountMetadata> = {isLocked : true, metadata: {name: ''}}; // error, metadata missing roles property
Zze
  • 18,229
  • 13
  • 85
  • 118