Search code examples
typescriptinterface

How to verify that type Foo only contains a subset of properties from type Bar?


I have one interface, AppState, and I want to be able to code against a subset of this main appstate interface so that I only pull properties which would be populated by a controller class somewhere further up in the pipeline. Eventually I want to be able to "connect" using a FooAppStateSubset so when developing we can easily pick out JUST the props that are relevant and set for our current section of the website.

How can I ensure that...

  1. FooAppStateSubset ONLY contains properties and values that could also be found within AppState interface
  2. FooAppStateSubset is not required to list the non optional parameters from AppState
  3. Fails at compile and build time if the first two rules are broken
  4. Autocomplete for properties would be a cool bonus. Fine if it isn't possible though.
  5. Would be nice to be able to define models all over the website without needing to have the master AppState interface implement all the scattered subset models.

MODELS:

interface AppState {
  email: string;
  userId: number;
  firstName?: string;
  isAwesome: boolean;
}


interface/type FooAppStateSubset {
  isAwesome: boolean;
  firstName?: string;
}

Solution

  • The simplest way if you have only a couple of properties would be to:

    type FooAppStateSubset = Omit<Omit<AppState, 'email'>, 'userId'>
    

    Otherwise a typeguard perhaps?

    function isSubset(something: AppState | FooAppStateSubset): something is FooAppStateSubset {
      return !('email' in something || 'userId' in something);
    }
    
    const foo = { isAwesome: true };
    isSubset(foo) && console.log(foo.email); // error!