如何修复打字稿处理函数重载和类型推断

问题描述 投票:0回答:1

我有这个游乐场,我想让它在我的情况下发挥作用。

type Person = {
  name: string;
  surname: string;
}

type User = Person & {
  username: string; 
}

type Name = string;

function createLogin(user: User, value: { nickName: string }): string;
function createLogin(user: Person, value: { name: string }): string;
function createLogin(user: any, value: any): string {
  return "It's not important";
}

const user: User = {
  name: "",
  surname: "",
  username: "",
};
const person: Person = {
  name: "",
  surname: "",
};

const result = createLogin(person, { name: "" });
const result2 = createLogin(user, { name: "" }); // <--- The problem is here
const result3 = createLogin(user, { nickName: "" });

我的问题是,对于 User 类型的用户(它是 Person 的超集)的

result2
,第二个参数
{ name: "" }
与第二个重载签名匹配。 TypeScript 选择与两种参数类型匹配的更具体的重载,但我想避免这种情况发生

提前感谢您的时间和帮助,非常感谢。

typescript function overloading type-inference
1个回答
0
投票

有几种方法可以克服这个问题:

第一个不同的错误:

type Person = {
  name: string;
  surname: string;
}

type User = Person & {
  username: string;
}

type Name = string;

function createLogin(user: User, value: { nickName: string }): string;
function createLogin(user: User, value: { name: string }): never; // return never
function createLogin(user: Person, value: { name: string }): string;
function createLogin(user: any, value: any): string {
  return "It's not important";
}

const user: User = {
  name: "",
  surname: "",
  username: "",
};
const person: Person = {
  name: "",
  surname: "",
};

const result = createLogin(person, { name: "" });
const result2 = createLogin(user, { name: "" }); // never, will raise an error later
const result3 = createLogin(user, { nickName: "" });

第二个使用可选的 never:

type BasePerson = {
  name: string;
  surname: string;
}

type Person = BasePerson & {
  username?: never;
}

type User = BasePerson & {
  username: string;
}

type Name = string;

function createLogin(user: User, value: { nickName: string }): string;
function createLogin(user: Person, value: { name: string }): string;
function createLogin(user: any, value: any): string {
  return "It's not important";
}

const user: User = {
  name: "",
  surname: "",
  username: "",
};
const person: Person = {
  name: "",
  surname: "",
};

const result = createLogin(person, { name: "" });
const result2 = createLogin(user, { name: "" }); // No overload matches this call.
const result3 = createLogin(user, { nickName: "" });

第三种是只接受严格类型:

type Person = {
  name: string;
  surname: string;
}

type User = Person & {
  username: string;
}

type Name = string;

type StrictType<A extends object, B extends object> = A extends B ? B extends A ? A : never : never;

function createLogin<T extends User>(user: StrictType<T, User>, value: { nickName: string }): string;
function createLogin<T extends Person>(user: StrictType<T, Person>, value: { name: string }): string;
function createLogin(user: any, value: any): string {
  return "It's not important";
}

const user: User = {
  name: "",
  surname: "",
  username: "",
};
const person: Person = {
  name: "",
  surname: "",
};

const result = createLogin(person, { name: "" });
const result2 = createLogin(user, { name: "" }); // never, will raise an error later
const result3 = createLogin(user, { nickName: "" });

© www.soinside.com 2019 - 2024. All rights reserved.