switch case语句中的Typescript类型安全性

Kwi*_*enP 5 typescript typescript2.0

我正在使用Redux,我正在尝试使我的减速器类型安全.我在ngrx-store/example应用程序中找到了一些代码示例,他们完全成功地做到了这一点.(https://github.com/ngrx/example-app/blob/master/src/app/actions/book.ts)

在将这个集成到我自己的项目中时,我发现了一些奇怪的东西,我无法解释.检查以下代码示例(内联注释):

// 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
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我将FIRST和SECOND属性的定义替换为以下内容,它确实有效.

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


const FIRST = type("FIRST");
const SECOND = type("SECOND");
Run Code Online (Sandbox Code Playgroud)

据我所知,type函数只将字符串强制转换为字符串.为什么代码在调用type函数时有效,但在立即声明字符串时却没有?

这是一个打字稿操场示例,您可以在其中注释定义(首先是工作版本).

Die*_*erg 2

这是因为 TSC 编译器无法区分这两个值:

const FIRST = "FIRST";
const SECOND = "SECOND";
Run Code Online (Sandbox Code Playgroud)

两者都是 type string,因此 TSC 不知道哪个属于哪个。您必须给它一个类型,这就是您通过使用type函数对其进行强制转换所做的事情。

但如果你这样写就更容易了:

const FIRST: "FIRST" = "FIRST";
const SECOND: "SECOND" = "SECOND";
Run Code Online (Sandbox Code Playgroud)

打字稿游乐场