最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - determine type of parameter that could have multiple types in typescript - Stack Overflow

programmeradmin1浏览0评论

Given a function with a parameter of different types, how do I find out which type was passed to the function?

Example

interface SomeCustomInterface {
    title: string
}

interface OtherCustomInterface {
    subtitle: string
}


interface A {
    value: string
}

interface B {
    value: number
}

interface C {
    value: SomeCustomInterface
}

interface D {
    value: OtherCustomInterface
}

function doSomething(parameter: A | B | C | D): string {
    switch(parameter.type) { 
        // I know the cases are not valid TS. What should I do instead?
        case A:
            return parameter.value
        case B:
            return parameter.value.toString()
        case C:
            return parameter.value.title
        case D:
            return parameter.value.subtitle
    }
}

I know that there are type guards but I have concerns with those

  1. They need to be able to uniquely identify each type. I see that some people add a property kind or type which allows them to identify a type in order to type guard it. This seems like a lot of overhead and boilerplate to me though.

  2. You need to write a custom function for each type like type is A or type is B which again would lead to massive overhead in my context.

What is the appropriate way to approach this in typescript?

Given a function with a parameter of different types, how do I find out which type was passed to the function?

Example

interface SomeCustomInterface {
    title: string
}

interface OtherCustomInterface {
    subtitle: string
}


interface A {
    value: string
}

interface B {
    value: number
}

interface C {
    value: SomeCustomInterface
}

interface D {
    value: OtherCustomInterface
}

function doSomething(parameter: A | B | C | D): string {
    switch(parameter.type) { 
        // I know the cases are not valid TS. What should I do instead?
        case A:
            return parameter.value
        case B:
            return parameter.value.toString()
        case C:
            return parameter.value.title
        case D:
            return parameter.value.subtitle
    }
}

I know that there are type guards but I have concerns with those

  1. They need to be able to uniquely identify each type. I see that some people add a property kind or type which allows them to identify a type in order to type guard it. This seems like a lot of overhead and boilerplate to me though.

  2. You need to write a custom function for each type like type is A or type is B which again would lead to massive overhead in my context.

What is the appropriate way to approach this in typescript?

Share Improve this question edited Jul 9, 2020 at 11:44 matteok asked Jul 9, 2020 at 11:35 matteokmatteok 2,2093 gold badges32 silver badges58 bronze badges 6
  • Would paring the type be enough? i.e. parameter.value being a number, string or object. If so, you could always use typeof? – Dane Brouwer Commented Jul 9, 2020 at 11:41
  • It might also be different types of objects. I updated my question – matteok Commented Jul 9, 2020 at 11:45
  • Does this answer your question? How to check the object type on runtime in TypeScript? – Dane Brouwer Commented Jul 9, 2020 at 11:47
  • I looked into this possibility but saw that it would create a lot of overhead. All the properties are named value so even if I create the 4 extra isA, isB, isC, isD methods I would still need to inspect the value for isSomeCustomType and isOtherCustomType and with this cascading requirement it would add too much overhead to support it in my project. – matteok Commented Jul 9, 2020 at 11:52
  • Why don't you check the typeof the parameter? You don't really need to access it's members for this. – user3647971 Commented Jul 9, 2020 at 12:23
 |  Show 1 more ment

1 Answer 1

Reset to default 3

Basically there are only 2 options as described in the accepted answer of this question.

What you can do is check that the shape of an object is what you expect, and TypeScript can assert the type at pile time using a user-defined type guard that returns true (annotated return type is a "type predicate" of the form arg is T) if the shape matches your expectation:

For class types you can use JavaScript's instanceof to determine the class an instance es from, and TypeScript will narrow the type in the type-checker automatically.

A side note from myself:

If you have the same propertyname you can potentially refactor your code using generics, like:

interface A {
    value: string
}

interface B {
    value: number
}

interface C {
    value: SomeCustomInterface
}

interface D {
    value: OtherCustomInterface
}

can be

interface GenericInterface<T>{
 value: T
}
发布评论

评论列表(0)

  1. 暂无评论