Skip to content

Typeguards with destructuring parameters #28311

Open
@lemoinem

Description

@lemoinem

Search Terms

Typeguard
type narrowing
destructuring

Suggestion

It'd be nice to be able to have typeguard functions with destructuring arguments.

Use Cases

When manipulating tuples or other anonymous structured types, whose typeguard relies only on a small part of the object, it would make the code much easier to read.
Currently, typeguards cannot be used with destructuring arguments, which makes it a weird special case.

Examples

const val: Array<[string, boolean]> = ([] as Array<[string | undefined, boolean]>)
    .filter(([foo, bar]: [string | undefined, boolean]): [foo, bar] is [string, boolean] => foo !== undefined);

const val2: Array<[string, boolean]> = ([] as Array<[string | undefined, boolean]>)
    .filter((val: [string | undefined, boolean]): val is [string, boolean] => val[0] !== undefined);

https://www.typescriptlang.org/play/index.html#src=const%20val%3A%20Array%3C%5Bstring%2C%20boolean%5D%3E%20%3D%20(%5B%5D%20as%20Array%3C%5Bstring%20%7C%20undefined%2C%20boolean%5D%3E)%0D%0A%20%20%20%20.filter((%5Bfoo%2C%20bar%5D%3A%20%5Bstring%20%7C%20undefined%2C%20boolean%5D)%3A%20%5Bfoo%2C%20bar%5D%20is%20%5Bstring%2C%20boolean%5D%20%3D%3E%20foo%20!%3D%3D%20undefined)%3B%0D%0A%0D%0Aconst%20val2%3A%20Array%3C%5Bstring%2C%20boolean%5D%3E%20%3D%20(%5B%5D%20as%20Array%3C%5Bstring%20%7C%20undefined%2C%20boolean%5D%3E)%0D%0A%20%20%20%20.filter((val%3A%20%5Bstring%20%7C%20undefined%2C%20boolean%5D)%3A%20val%20is%20%5Bstring%2C%20boolean%5D%20%3D%3E%20val%5B0%5D%20!%3D%3D%20undefined)%3B%0D%0A%0D%0Aconst%20val3%3A%20string%5B%5D%20%3D%20(%5B%5D%20as%20Array%3Cstring%20%7C%20undefined%3E)%0D%0A%20%20%20%20.filter((foo%3F%3A%20string)%20%3D%3E%20foo%20!%3D%3D%20undefined)%3B%0D%0A

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript / JavaScript code
    This wouldn't change the runtime behavior of existing JavaScript code
    This could be implemented without emitting different JS based on the types of the expressions
    This isn't a runtime feature (e.g. new expression-level syntax)

Activity

added
SuggestionAn idea for TypeScript
Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this feature
on Nov 2, 2018
jamesblack

jamesblack commented on Jul 1, 2019

@jamesblack

I'm afraid of bumping a super old thing, but I think i'm running into something that would be resolved if this was.

Given this function

export function toPolicy (value: any): [string[], null] | [null, Policy] {
  try {
    return [null, policyJSONSchema.validateSync(value) as Policy]
  } catch (err) {
    return [err.errors, null]
  }
}

Given this callsite

const [validationErrors, policy] = toPolicy(req.body)
      if (validationErrors !== null) {
        throw new BadRequest(`invalid policy: ${validationErrors.join(', ')}`)
      }
      found.version = policy.version

The policy.version policy is coming back as possiby null, even though it cannot be null if validation errors is null.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @lemoinem@jamesblack@weswigham

        Issue actions

          Typeguards with destructuring parameters · Issue #28311 · microsoft/TypeScript