简体   繁体   中英

Define type when destructuring an array

I would like to define type when destructuring an array, But it shows some error:

interface buildTargetProps {
  target: string;
  path: string;
}
interface buildTargets {
  [property: string]: buildTargetProps
};


const ChooseApp: buildTargets = {
  'autocomplete': {
    target: "test",
    path: "./Autocomplete",
  },
  'search': {
    target: "search-root",
    path: "./Search",
  },
};


let [applicationToBuild] = Object.entries(ChooseApp).find(
  ([name, props]: [String, buildTargetProps]) => {
    if (document.getElementById(props.target)) {
      return name;
    }
  }
);

What I want to do is defined the type of "applicationToBuild" variable, for that I have Tried:

let [applicationToBuild]: [string] | undefined  = Object.entries(ChooseApp)

I intentionally skipped the other array element, as I don't need that, But I tried to add that as well, to check if that resolves the error, But that also didn't work.

let [applicationToBuild, otherprops]: [string, buildTargetProps] | undefined  = Object.entries(ChooseApp)

But, this throws an error.

Type '[string, buildTargetProps] | undefined' is not assignable to type '[string] | undefined'.
  Type '[string, buildTargetProps]' is not assignable to type '[string]'.
    Source has 2 element(s) but target allows only 1.ts(2322)
Type '[string] | undefined' is not an array type.ts(2461)

You are iterating on the entries of the JSON object. Essentially, you are dealing with an array of tuples that looks like this:

[ 
  [ 
    'autocomplete', 
    {
      target: "test",
      path: "./Autocomplete",
    }
  ],
  [
    'search',
    {
      target: "search-root",
      path: "./Search",
    }
  ]
]

The .find function returns the first object that matches the criteria (one that return a truthy value) provided in the callback function. So, it returns the tuple of the shape [string, {target: string, path: string}] . But, in case it does not match anything it returns undefined. And, that's where the problem is. In case where returns undefined, the destructure won't work. So, you return an empty array just to make sure the destructure work and the value is assigned to undefined .

Here is a shorter version:

interface buildTargetProps {
  target: string;
  path: string;
}
interface buildTargets {
  [property: string]: buildTargetProps
};


const ChooseApp: buildTargets = {
  'autocomplete': {
    target: "test",
    path: "./Autocomplete",
  },
  'search': {
    target: "search-root",
    path: "./Search",
  },
};


let [applicationToBuild] = Object
  .entries(ChooseApp)
  .find(
    ([_, props]) => !!document.getElementById(props.target)
  ) || 
  [];

console.log(applicationToBuild)

TS Playground

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