gpt4 book ai didi

javascript - 为什么 typescript 不允许在字符串中调用 concat |字符串 [] 类型?

转载 作者:搜寻专家 更新时间:2023-10-30 21:06:29 25 4
gpt4 key购买 nike

const s: string = 'foo';

const pass1 = (origin: string) => origin.concat(s);
const pass2 = (origin: string[]) => origin.concat(s);

type S = string | string[];

const error = (origin: S) => origin.concat(s);

上面的代码。我可以在 stringstring[] 类型中调用 concat。那么为什么 TypeScript 不允许在 string | 中调用 concat字符串[]类型?

错误是:

Cannot invoke an expression whose type lacks a call signature.
Type '((...strings: string[]) => string) | { (...items: ConcatArray<string>[]): string[]; (...items: (s...'
has no compatible call signatures.

因为它们有不同的返回类型?但我认为 TS 可以推断出 error 的类型是 S。是故意设计的吗?如果是,为什么?

最佳答案

因为虽然 concat 方法在这两种类型之间是通用的,但它在两者之间具有非常不同的签名,所以 Typescript 无法真正合并方法的声明。虽然不理想,但您可以使用类型保护来区分这两种类型:

const s: string = 'foo';
type S = string | string[];

const error = (origin: S) => typeof origin === 'string' ?
origin.concat(s) :
origin.concat(s);

或者只是断言为 any :

const s: string = 'foo';
type S = string | string[];

const error = (origin: S) => (origin as any).concat(s) as S

还有一个选项可以将签名的并集转换为签名的交集。这在某些情况下可能很有效,但在其他情况下可能效果不佳:

const s: string = 'foo';
type S = string | string[];

type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

function mergeSignature<T, K extends keyof T> (value: T, method: K) : UnionToIntersection<T[K]>{
return ((...args: any[]) => (value[method] as any as Function).apply(value, args)) as any;
}

const error = (origin: S) => mergeSignature(origin, 'concat')(s);

关于javascript - 为什么 typescript 不允许在字符串中调用 concat |字符串 [] 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50851023/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com