Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typescript typing encapsulation

In the following example, I seek to describe a complex typescript type that I want to use later FinalType. The thing is, due to it's complexity, this type required the declaration of intermediary types that are polluting the page IntermediaryType/IntermediaryType2.

Playground

type IntermediaryType = {
  decisiveKey: true,
  mutatedKey: (params: any) => void,
} | {
  decisiveKey: false,
  mutatedKey?: false,
}

interface IntermediaryType2 {
  foo?: string,
  bar?: boolean,
}

type FinalType = IntermediaryType & IntermediaryType2;

const Foo = (param: FinalType) => {}

Foo({
  decisiveKey: true,
  mutatedKey: () => {},
});

My question is, is there any way to makes the intermediary types unreachable, and only allow the use of FinalType ?


I've seen that you can enclosure some part of the code using brackets like :

{
  type IntermediaryType = {
    decisiveKey: true,
    mutatedKey: (params: any) => void,
  } | {
    decisiveKey: false,
    mutatedKey?: false,
  }

  interface IntermediaryType2 {
    foo?: string,
    bar?: boolean,
  }

  type FinalType = IntermediaryType & IntermediaryType2;
}

const Foo = (param: FinalType) => {}

Foo({
  decisiveKey: true,
  mutatedKey: () => {},
});

But then I obviously can't access FinalType. I've tried to use return or export but none works.

The ideal would be something like :

type FinalType = {
  type IntermediaryType = {
    decisiveKey: true,
    mutatedKey: (params: any) => void,
  } | {
    decisiveKey: false,
    mutatedKey?: false,
  }

  interface IntermediaryType2 {
    foo?: string,
    bar?: boolean,
  }

  return IntermediaryType & IntermediaryType2;
}

const Foo = (param: FinalType) => {}

Foo({
  decisiveKey: true,
  mutatedKey: () => {},
});

Any leads ?



Using @Aluan Haddad answer, for now the best I can achieve is :

namespace _ {
    type IntermediaryType = {
        decisiveKey: true,
        mutatedKey: (params: any) => void,
    } | {
        decisiveKey: false,
        mutatedKey?: false,
    }

    interface IntermediaryType2 {
        foo?: string,
        bar?: boolean,
    }

    export type FinalType = IntermediaryType & IntermediaryType2;
}; type FinalType = _.FinalType;

const Foo = (param: FinalType) => {}

Foo({
  decisiveKey: true,
  mutatedKey: () => {},
});

I would love to add some syntax sugar on it!

like image 553
Orelsanpls Avatar asked Oct 16 '22 03:10

Orelsanpls


2 Answers

What your are literally trying to do, introducing arbitrary scopes for types, can be accomplished via a TypeScript namespace.

declare namespace myNamespace {
  type IntermediaryType = {
    decisiveKey: true,
    mutatedKey: (params: any) => void,
  } | {
    decisiveKey: false,
    mutatedKey?: false,
  }

  interface IntermediaryType2 {
    foo?: string,
    bar?: boolean,
  }

  export type FinalType = IntermediaryType & IntermediaryType2;
}

const Foo = (param: myNamespace.FinalType) => {}

Foo({
  decisiveKey: true,
  mutatedKey: () => {},
});

However, if you are writing modern code, and therefore using modules, namespaces should almost always be avoided. Fortunately, if you're are using modules the solution is even simpler; don't export the intermediate types.

type IntermediaryType = {
  decisiveKey: true,
  mutatedKey: (params: any) => void,
} | {
  decisiveKey: false,
  mutatedKey?: false,
}

interface IntermediaryType2 {
  foo?: string,
  bar?: boolean,
}

export type FinalType = IntermediaryType & IntermediaryType2;

export const Foo = (param: FinalType) => {}

Foo({
  decisiveKey: true,
  mutatedKey: () => {},
});
like image 141
Aluan Haddad Avatar answered Oct 19 '22 02:10

Aluan Haddad


I'm not sure about your preface

due to it's complexity, this type required the declaration of intermediary types

this compiles

type FinalType = (
  | {
      decisiveKey: true;
      mutatedKey: (params: any) => void;
    }
  | {
      decisiveKey: false;
      mutatedKey?: false;
    }
) & {
  foo?: string;
  bar?: boolean;
};

const Foo = (param: FinalType) => {};

Foo({
  decisiveKey: true,
  mutatedKey: () => {}
});

Hope this helps.

like image 26
Daniele Ricci Avatar answered Oct 19 '22 02:10

Daniele Ricci