【问题标题】:Why does TypeScript not report this typing mistake?为什么 TypeScript 不报告这个打字错误?
【发布时间】:2020-02-22 10:17:00
【问题描述】:

我有以下代码:

   authUserListener = (next: (newUser: AuthUser) => void, fallback: () => void): Unsubscribe => {
    return this.auth.onAuthStateChanged((user: firebase.User | null) => {
      console.log(user);
      if (user) {
        this.user(user.uid).on("value", (snapshot: firebase.database.DataSnapshot) => {
            const databaseUser = snapshot.val();
            // Merge Auth and Database user
            const mergedUser: UserData = {
              uid: user.uid,
              email: user.email,
              ...databaseUser,
            };
            next(mergedUser);
          },
        );
      } else {
        fallback();
      }
    });
  };

这个类方法是这样调用的:

const unsubscribeFromListener = firebase.authUserListener(
      (newUser: UserData) => {
        const different = newUser === user;
        if (different || user === null) {
          setUser(newUser);
        }
      },
      () => {
        if (user !== null) {
          setUser(null);
        }
      },
    );

代码运行良好!但是,我注意到我将UserData 类型的变量传递给期望AuthUser 类型的函数。这些类型定义为:

type UserData = {
  uid: string;
  email: string;
  username: string;
};

type AuthUser = "uninitialized" | null | UserData;

authUserListener 方法中,我调用next 函数,它作为参数传递,变量类型为UserData,而我说authUserListener 接收一个函数next,它是类型(newUser: AuthUser) => void,所以它的参数是类型AuthUser。正如您在上面看到的,这两种类型并不相同。为什么 TypeScript 没有警告我将错误的类型传递给 next 函数这一事实?

【问题讨论】:

  • 您能否提供一个独立的minimal reproducible example,如How to Ask 中所述,以便我可以将其放入the Playground 之类的Web IDE 中并为自己演示这个问题?乍一看,看起来一切都很好...... (arg: A | B | C) => void 类型的函数说“我接受 ABC 参数”,所以它会很高兴用参数调用输入A。你应该总是能够给接受超类型的人一个类型的值。

标签: typescript types


【解决方案1】:

UserDataAuthUser 的有效类型。您已将其创建为null"uninitialized"UserData,因此UserData 类型的任何参数都是AuthUser 类型的有效实例化。

如果你取出其他的,你的声明是type AuthUser = UserData(或者它可能是字符串文字“未初始化”或者它可能是null)。

如果你说它可能是"3" | "5" | "6" 并且你传入“6”,你会认为它是有效的,对吧?同样的,你已经为你创建的类型传入了一个有效的实例。

这样说清楚了吗?

【讨论】:

    猜你喜欢
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 2011-02-22
    • 1970-01-01
    • 2011-07-02
    • 2013-02-07
    • 1970-01-01
    相关资源
    最近更新 更多