2016-11-16 7 views
5

मैं रेडक्स के साथ काम कर रहा हूं और मैं अपने रेड्यूसर को सुरक्षित रखने की कोशिश कर रहा हूं। मुझे ngrx-store/example ऐप से कुछ कोड उदाहरण मिला जहां वे इसे करने में पूरी तरह सफल हुए। (https://github.com/ngrx/example-app/blob/master/src/app/actions/book.ts)स्विच केस स्टेटमेंट्स में टाइपस्क्रिप्ट प्रकार की सुरक्षा

अपनी खुद की परियोजना में इसे एकीकृत करते समय, मैंने कुछ अजीब देखा, जिसे मैं समझा नहीं सकता। अगर मैं निम्नलिखित में FIRST और SECOND गुण की परिभाषा को बदलने के

// Action has a type and payload property 
interface Action { 
    type: string; 
    payload?: any; 
} 

// Here I declare the action types as plain strings 
const FIRST = "FIRST"; 
const SECOND = "SECOND"; 

// I create classes for every action with there respective types 
class FirstAction implements Action { 
    public type = FIRST; 
    payload: { id: number }; 

    public constructor(id: number) { 
     this.payload = { id }; 
    } 
} 

class SecondAction implements Action { 
    public type = SECOND; 

    public constructor() { } 
} 

// Create a union type 
type Actions = FirstAction | SecondAction; 

// Use the union type as type parameter in my function 
function test(action: Actions): void { 
    switch (action.type) { 
     case FIRST: 
        // compiler will complain it cannot find the payload 
        // property on Actions 
      let temp = action.payload.id; 
     case SECOND: 
     // empty 
     default: 
     //empty 
    } 
} 

, यह काम करता है: निम्नलिखित कोड नमूना (कुछ टिप्पणियाँ इनलाइन) की जाँच करें।

export function type<T>(label: T | ''): T { 
    return <T>label; 
} 


const FIRST = type("FIRST"); 
const SECOND = type("SECOND"); 

जहां तक ​​मैं देख सकता हूं, प्रकार फ़ंक्शन केवल स्ट्रिंग को स्ट्रिंग पर रखता है। कोड type फ़ंक्शन को कॉल करने के साथ क्यों काम करता है लेकिन स्ट्रिंग को तुरंत घोषित करते समय नहीं?

यहां एक typescript playground example है जहां आप केवल परिभाषाओं को बाहर या बाहर (पहले वर्किंग संस्करण के साथ) टिप्पणी कर सकते हैं।

उत्तर

2

यह क्योंकि टीएससी संकलक अलग नहीं कर सकते हैं 2 मूल्यों है:

const FIRST = "FIRST"; 
const SECOND = "SECOND"; 

यह प्रकार string के दोनों है, इस प्रकार टीएससी जो के अंतर्गत आता है पता नहीं है। आपको इसे एक प्रकार देना होगा, और यही वह है जो आप इसे अपने type फ़ंक्शन के साथ कास्टिंग करके कर रहे हैं।

लेकिन यह आसान है अगर आप इसे लिखते इस प्रकार है:

let temp = (action as FirstAction).payload.id; 

कुछ अन्य विचार:
- क्या तुम सच में क्या

const FIRST: "FIRST" = "FIRST"; 
const SECOND: "SECOND" = "SECOND"; 

Typescript playground

+0

मैं इस धारणा के तहत था कि यदि आप 'प्रकार ("FIRST")' कहलाते हैं, तो टी जेनेरिक एक स्ट्रिंग होगा लेकिन स्पष्ट रूप से यदि "FIRST" होगा, तो सही होगा? यदि मैं वर्णन कर रहा था, तो मुझे उम्मीद थी कि टीएससी स्ट्रिंग मानों की तुलना करने के लिए पर्याप्त स्मार्ट हो जाएगा ताकि यह पता चल सके कि स्विच स्टेटमेंट के उस हिस्से में किस तरह की कार्रवाई की गई थी। – KwintenP

+0

हां, अगर आप इसे इस तरह डालेंगे तो यह 'FIRST' टाइप होगा। टीएससी मूल्य नहीं जान सकता है, यह संभव हो सकता है कि मूल्य बदल जाएंगे। भले ही आप इसे एक कॉन्स्ट के रूप में घोषित करते हैं, फिर भी आपके 'एक्शन' कक्षाओं में मूल्य बदल सकते हैं। मतलब आप 'FIRST' के विरुद्ध 'स्ट्रिंग' की तुलना कर रहे थे। – Dieterg

-1

मैं as ऑपरेटर का प्रयोग करेंगे Actions की आवश्यकता है यदि आपके पास पहले से Action है कि सभी आपकी क्रिया कक्षाएं लागू होती हैं?
- फ़ंक्शन में प्रत्येक मामले के रेड्यूसर को निकालने से पठनीयता और इकाई परीक्षण में मदद मिल सकती है।
- याद रखें कि reducers राज्य और कार्रवाई लेते हैं, और राज्य लौटते हैं (मैं समझता हूं कि आपने बस अपना उदाहरण सरलीकृत किया है)।

function test(state: State, action: Action): State { 
    switch (action.type) { 
     case FIRST: 
      return handleFirst(state, action as FirstAction); 
     case SECOND: 
      return handleSecond(state, action as SecondAction); 
     default: 
      return state; 
    } 
} 

function handleFirst(state: State, action: FirstAction): State { 
    let temp = action.payload.id; 
    // ... 
} 

// ... 
+0

मैं वास्तव में इस से सहमत नहीं हूं। इस मामले में आप 'हे, यह एक फर्स्टएक्शन' कहकर टाइपस्क्रिप्ट की प्रकार की जांच को ओवरराइड कर रहे हैं। इसमें कोई मूल्य या प्रकार सुरक्षा नहीं है। आप केवल 'फर्स्टएक्शन' के लिए जो भी मूल्य डाल सकते हैं। – KwintenP

0

यह केवल स्थिर अभिव्यक्तियों, नियमित रूप से नहीं, स्थिरता के साथ काम करता है।

switch(variable_expression) { 
    case constant1: { 
     //code; 
     break; 
    } 
    case constant2: { 
     //code; 
     break; 
    } 
    default: { 
     //code; 
     break; 
    } 
} 
संबंधित मुद्दे