TypeScript:返回一个通用类型的函数,它扩展了Record<string,string&gt。

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

我想创建一个 parse<Type>() 函数来解析一个字符串并返回一个对象,但我想用 parse() 来返回正确的类型,而我正在努力。

type Identity = {
  name: string;
};

type ContactDetails = {
  phone: string;
  email: string;
};

function parse<T extends Record<string, string>>(input: string): T {
  const result = {};
  input.split('&').forEach(bits => {
    const [name, value] = bits.split('=');
    result[name] = value;
  });
  return result;
}

parse<Identity>('name=Paulin');
parse<ContactDetails>('phone=0123456789&[email protected]');

我得到一个TypeScript错误。

类型'{}'不可分配给类型'T'. '{}'可分配给'T'类型的约束,但'T'可以用不同的约束子类型'Record'来实例化.ts(2322)

我明白问题出在哪里了。{} 是不兼容的通用 Record 型。但如何解决这个问题?

非常感谢您!我想创建一个解析类型。

typescript generics
1个回答
1
投票

我很确定这是你必须求助于类型断言的地方之一。在这种情况下。

function parse<T extends Record<string, string>>(input: string): T {
  const result: Record<string, string> = {};
// −−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^
  input.split('&').forEach(bits => {
    const [name, value] = bits.split('=');
    result[name] = value;
  });
  return result as T;
// −−−−−−−−−−−−^^^^^
}

在操场上

但重要的是要明白这里的局限性。如果你的 IdentityContactDetails 类型有特定的实现(在你的例子中没有,它们只是 interfaces),对象 parse 返回不会得到该实现的支持。它 仅仅 Record<string, string>. 所以你最好是有 parse 归还 Record<string, string> 而不是,让调用者对类型做出明智的决定。


0
投票

根据T.J.Crowder的建议:让调用者对类型做出决定,这是我的最终实现。

type Identity = {
  name: string;
};

type ContactDetails = {
  phone: string;
  email: string;
};

function parse(input: string): Record<string, string> {
  const result: Record<string, string> = {};
  input.split('&').forEach(bits => {
    const [name, value] = bits.split('=');
    result[name] = value;
  });
  return result;
}

const identity = parse('name=Paulin') as Identity;
const details = parse('phone=0123456789&[email protected]') as ContactDetails;

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