【问题标题】:type: typeof variable vs type: string类型:类型变量与类型:字符串
【发布时间】:2020-01-07 21:38:16
【问题描述】:

在我构建 react redux 应用程序时收到警告消息:

"message": "Type '{ type: string; payload: Text[]; }' 不可分配给 type 'MessageAction'。\n 属性 'type' 的类型不兼容。\n Type 'string' 是不可分配给类型 '\"MESSAGES_ACTIONS_SUCCESS\"'.",

所以:

src/pages/home/modules/types.ts中的1和2有什么不同

// src/pages/home/modules/types.ts
1. got warn msg
export const MESSAGES_ACTIONS_SUCCESS = "MESSAGES_ACTIONS_SUCCESS"

export interface MessageAction {
  type: typeof MESSAGES_ACTIONS_SUCCESS
  payload: Text[]
}

2.no warn msg
export const MESSAGES_ACTIONS_SUCCESS = "MESSAGES_ACTIONS_SUCCESS"

export interface MessageAction {
  type: string
  payload: Text[]
}
// src/pages/home/modules/actions.ts
import { Dispatch } from "redux"

import { MESSAGES_ACTIONS_SUCCESS, MessageAction } from "./types"

export const loadMessageData = () => async (
  dispatch: Dispatch
): Promise<MessageAction> => {
  const messages: Text[] = await new Promise(resolve => {
    setTimeout(() => resolve([{ text: "home ~~~~~~" }]))
  })

  return dispatch({
    type: MESSAGES_ACTIONS_SUCCESS,
    payload: messages
  })
}

更多信息代码回购是 https://github.com/77xi/SSR/pull/5

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我重写了您提供的代码以创建一个稍微简单的失败案例:

    const MESSAGES_ACTIONS_SUCCESS = "MESSAGES_ACTIONS_SUCCESS";
    
    interface MessageActionOne {
      type: typeof MESSAGES_ACTIONS_SUCCESS;
      payload: Text[];
    }
    
    interface MessageActionTwo {
      type: string;
      payload: Text[];
    }
    
    // Infered type will be: { type: string; payload: never[]; }
    const action = {
      type: MESSAGES_ACTIONS_SUCCESS,
      payload: []
    };
    
    const one: MessageActionOne = action;
    //    ^^^  Type 'string' is not assignable to type '"MESSAGES_ACTIONS_SUCCESS"'
    

    Here is the TypeScript playground

    问题在于,在此示例中 action 被推断为 type: string 而不是 type: "MESSAGES_ACTIONS_SUCCESS"

    如果您用as const 更新了第一行,应该可以解决这个打字问题:

    const MESSAGES_ACTIONS_SUCCESS = "MESSAGES_ACTIONS_SUCCESS" as const;
    
    interface MessageActionOne {
      type: typeof MESSAGES_ACTIONS_SUCCESS;
      payload: Text[];
    }
    
    interface MessageActionTwo {
      type: string;
      payload: Text[];
    }
    
    // Infered type will be: { type: "MESSAGES_ACTIONS_SUCCESS"; payload: never[]; }
    const action = {
      type: MESSAGES_ACTIONS_SUCCESS,
      payload: []
    };
    
    const one: MessageActionOne = action;
    

    Here is the TypeScript playground for the fixed example.

    const 断言已在 TypeScript 3.4 和 you can read more here about them 中添加。突出显示的第一个问题是您遇到的问题:

    不应扩大该表达式中的文字类型(例如,不要从“hello”变为字符串)

    【讨论】:

    • export const MESSAGES_ACTIONS_SUCCESS: string = "MESSAGES_ACTIONS_SUCCESS" 也可以解决这个问题
    • 是的,但是你会失去一些类型安全性。
    • 也得到 lint err 从字符串文字中简单推断的类型字符串,删除类型注释 @typescript-eslint/no-inferrable-types
    猜你喜欢
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    相关资源
    最近更新 更多