在Typescript中,是否有一种方法可以为switch语句中的case进行类型转换?

huangapple go评论61阅读模式
英文:

Typescript is there a way to cast type for case in switch?

问题

I have a function that checks request data to access an API endpoint. For each endpoint, there can be different preloaded data for this specific endpoint.

The problem is that for every operation, I need to cast request data to the endpoint data type. Is there a way to assert it only one time for the case block scope? Or should I take a different approach?

[Playground](https://www.typescriptlang.org/play/index.html?ssl=21&ssc=6&pln=1&pc=1#code/FAAjIFwTwBwUxAJTgRwDwBUQF4QFcA7AawIHsB3AgPhxAG8Q4CATGUgSwIgC4QBnCACdOAcwA0IZgEMIU3hgC ocMrDR4IAKIsAjLQHCCI1ZFgJtzAEwB9AMy0CeALYAjOIJMmAxqQICQXgAWcF5EiKQANgi4ABSCqLyEJBQEAJS8LqSRcFIEODR0JuD85OwQQSAxcaggUnxIqKkAdEysHFyp9EXF4F51CADkrWxcOgO8hT1TPewAZlXxKLX1yOgWOlTN0rK0A4HsA53xEHiCeUJ4CCDdU0rTPX18g8O EJbjNw-9IEMsIxC2cZde73apLOoNNYsGy2TZNbZSEAAalwOgA3J9QYtlpC0BYYXCESAAFSojEg6ZgnGrPHQuyEmSIgC0ZMx0zmCxqEJp PpW0ZtAArEc4CczpBBJcwGywHcKZI4LMpHgIjwQMdTnklREnp85bKgA)

type Req<T = unknown> = { endpoint: string, data: T }

type End1 = string
type End2_3 = number

const checkRole = (req: unknown): boolean => {
switch ((req as Req).endpoint) {
case 'endpoint1': {
if ((req as Req).data === 'hi') return true
}
case 'endpoint2':
case 'endpoint3': {
(req as Req<End2_3>).data += 1;
(req as Req<End2_3>).data *= 1;
(req as Req<End2_3>).data -= 1;
if ((req as Req<End2_3>).data === 5) return true
}
default: return false
}
}

UPD. [Variant that Jared suggested](https://www.typescriptlang.org/play/index.html?ssl=1&ssc=1&pln=27&pc=2#code/MYewdgzgLgBAlhAKjAvDAPIgfACgE4CmAjgFwwCuYA1mCAO5gCUZhR8EMyKWMA3gFAwhMQlHJ4wMKHnIF AX36DhUAJ4AHAjABKxTKgrVaDHml4wCYACbqQcMFDLQ89gOYAaGFYCGUb2URFYRhlITVNGABRawBGA2c3UKkNLWirACYAfQBmAzByAFsAIwI8JKTQSFhgAAsCYCptEAAbLTR8YjJKGnomMiKQFoJvSW4 JOCIOjgoWpgcDrZvDl0iRgA6Sxs7B0Zx4IPhYGWtAHIt2wcY07IBQ-vhOAAzBdYYZZ09NJisDZ8-AynGpwU57UTiSTSWRCCb3IIPI4nGDnayXKDpG6ww7HCBnC7gKDZG77BGHZ7zBCIdCrdBpLLZLC4ViMPZ3UkI1jrf7eGAAajQMQA3Fj2UJOdy QLhaKHuLfDz TAhSLRXKAYrlTL7uCJFIZFoQlqhPDSSaEVYCE9vORmo4RAQxLqrc1cSLFPIgA

英文:

I have a function that check request data to access api endpoint. For each endpoint there can be different preLoaded data for this specific endpoint.

Problem is that for every operation i need to cast request data to endpoint data type. Is there a way to assert it only one time for case block scope? Or i should take some different approach.

Playground.

type Req&lt;T = unknown&gt; = { endpoint: string, data: T}

type End1 = string
type End2_3 = number

const checkRole = (req: unknown): boolean =&gt; {
    switch ((req as Req).endpoint) {
        case &#39;endpont1&#39;: {
            if((req as Req&lt;End1&gt;).data = &#39;hi&#39;) return true  
        }
        case &#39;endpont2&#39;:
        case &#39;endpont3&#39;: {
            (req as Req&lt;End2_3&gt;).data += 1;
            (req as Req&lt;End2_3&gt;).data *= 1;
            (req as Req&lt;End2_3&gt;).data -= 1;
            if((req as Req&lt;End2_3&gt;).data = 5) return true  
        }
        default: return false
    }
}

UPD. Variant that jared suggested.

答案1

得分: 2

根据您的用例具体情况,您可能会对判别联合感兴趣:


type Req = { endpoint: "endpoint1", data: string }
    | { endpoint: "endpoint3" | "endpoint2", data: number }

const checkRole = (_req: unknown): boolean => {
    let req = _req as Req;
    switch (req.endpoint) {
        case 'endpoint1': {
            if (req.data === 'hi') return true;
            return false;
        }
        case 'endpoint3':
        case 'endpoint2': {
            req.data += 1;
            req.data *= 1;
            req.data -= 1;
            if (req.data === 5) return true;
        }
        default: return false;
    }
}

Playground链接

英文:

Depeding on the specifics of your use case, you might be interested in discriminated unions:


type Req = { endpoint: &quot;endpoint1&quot;, data: string }
    | { endpoint: &quot;endpoint3&quot; | &quot;endpoint2&quot;, data: number }

const checkRole = (_req: unknown): boolean =&gt; {
    let req = _req as Req;
    switch (req.endpoint) {
        case &#39;endpoint1&#39;: {
            if (req.data = &#39;hi&#39;) return true
            return false;
        }
        case &#39;endpoint3&#39;:
        case &#39;endpoint2&#39;: {
            req.data += 1;
            req.data *= 1;
            req.data -= 1;
            if (req.data == 5) return true
        }
        default: return false
    }
}

Playground Link

huangapple
  • 本文由 发表于 2020年1月7日 00:57:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/59616071.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定