简体   繁体   中英

How do I Define a Countries Type with optional keys paired to types of countries in Typescript?

I want to create a type of country region map of sorts to avoid making mistakes when selecting a country and it's respective region.

I also do not want to include every country and region ever mapped, just the ones that are relevant. Where the keys to the root type (Countries) may or may not exist (as the programmer may select only one of the listed countries), but each key if it exists has a mapped type with enforced values; once you select a root key you are committed until final selection.

Here is my attempt:

countries.ts

type Countries = {
  france?: France
  italy?: Italy
  spain?: Spain
}

type France = {
  mainRegions: {
    northanFrance?: NorthanFrance
    centralFrance?: CentralFrance
    southernFrance?: SouthernFrance
  }
}

type NorthanFrance = {
  subRegions: SubRegionsInNorthanFrance
}
type CentralFrance = {
  subRegions: SubRegionsInCentralFrance
}
type SouthernFrance = {
  subRegions: SubRegionsInSouthernFrance
}

type SubRegionsInNorthanFrance = 'Paris'|'Brittany'|'Normandy'|'Picardy';
type SubRegionsInCentralFrance = 'Dordogne'|'Jura & The Alps'|'Vendee'|'Loire';
type SubRegionsInSouthernFrance = 'Gironde & Charente-Maritime'
|'Landes & The Pyrenees'|'Languedoc & Roussillon'|'Ardeche & Auvergne'
|'Riviera & Provence'|'Corsica';

type Italy = {
  mainRegions?: {
    northanItaly?: NorthanItaly
    centralItaly?: CentralItaly
  }
}
type NorthanItaly = {
  subRegions: SubRegionsInNorthanItaly
}
type CentralItaly = {
  subRegions: SubRegionsInCentralItaly
}

type SubRegionsInNorthanItaly = 'Adriatic Coast & Venetian Riviera'|'Lake Garda';
type SubRegionsInCentralItaly = 'Tuscany & Elba'|'Lazio & Campania'|'Sardinia';

type Spain = {
  mainRegions: MainRegionsInSpain
}
type MainRegionsInSpain = 'Costa Brava, Costa Dorada & Costa Verde';

functions.ts

export function selectCountryAndRegion(country: Country, region: Countries = {}): void {
  // do something special with countries
}

some-test.spec.ts

it('should select one region from one country', function () {
    selectCountryAndRegion('France', {
      france: {
        mainRegions: {
          northanFrance: {
            subRegions: 'Brittany'
          }
        }
    });
  });

Unfortunately it makes me enter every country in the test case ie italy and spain in the root type.

Figured it out!

The Root Type Needs to Have OR logic around its type.

type Countries = {
  france?: France | undefined
  italy?: Italy | undefined
  spain?: Spain | undefined
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM