TypeScript "Concreting"泛型的行为与通过值推断的泛型行为不同,

uqdfh47h  于 6个月前  发布在  TypeScript
关注(0)|答案(2)|浏览(43)

Bug报告

🔎 搜索词

'T' 可以被示例化为与 'T' 无关的任意类型

🕗 版本及回归信息

在 v4.6.2 中测试

⏯ Playground链接

Playground

💻 代码

interface Monad<A> { Array: A[] }
type MonadIdentifier = keyof Monad<unknown>

declare const setBindArray:
  (bind: <A, B>(g: (a: A) => Monad<B>["Array"]) => (fa: Monad<A>["Array"]) => Monad<B>["Array"]) => void

setBindArray(g => fa => fa.flatMap(g))

declare const setBindGeneric:
  <I extends MonadIdentifier>
    ( idenfier: I
    , bind: <A, B>(g: (a: A) => Monad<B>[I]) => (fa: Monad<A>[I]) => Monad<B>[I]
    ) => void

setBindGeneric("Array", g => fa => fa.flatMap(g))
//                                 ~~~~~~~~~~~~~
// Type 'B[]' is not assignable to type 'B[]'. Two different types with this name exist, but they are unrelated.
//   Type 'B' is not assignable to type 'B'. Two different types with this name exist, but they are unrelated.
//     'B' could be instantiated with an arbitrary type which could be unrelated to 'B'.(2719)

🙁 实际行为

代码无法编译。

🙂 预期行为

代码应该可以编译。setBindArraysetBindGeneric 本质上是相同类型的函数,而 setBindArrayI 具体化为 "Array",而 setBindGeneric 通过第一个参数推断出 I"Array"

kr98yfug

kr98yfug1#

最低库存:

declare const fn1:    (cb: <T>(g: () => T) => () => T) => void;
declare const fn2: <U>(cb: <T>(g: () => T) => () => T) => void;
// notice the U is a unused type parameter

fn1(g => () => g()); // OK
fn2(g => () => g()); // Error ts2719

在OP的例子中:

declare const setBindArray:
  (bind: <A, B>(g: (a: A) => Monad<B>["Array"]) => (fa: Monad<A>["Array"]) => Monad<B>["Array"]) => void

setBindArray(g => fa => fa.flatMap(g)); // OK

declare const setBindArray2:
  <T>(bind: <A, B>(g: (a: A) => Monad<B>["Array"]) => (fa: Monad<A>["Array"]) => Monad<B>["Array"]) => void

setBindArray2(g => fa => fa.flatMap(g)); // Error ts2719
9w11ddsr

9w11ddsr2#

我不确定这是否相关,但当我给出错误的代码时,我也收到了不正确的错误信息:

function convertToNull<T>(input: T): T {
  return input ?? null;
}

TS Playground链接
显然,由于 null 并不总是可以分配给 T,所以会出现错误 Type 'NonNullable<T> | null' is not assignable to type 'T'.,但我期望得到提示 Type 'null' is not assignable to type 'T',而我收到的是
'T' could be instantiated with an arbitrary type which could be unrelated to 'NonNullable<T> | null'

相关问题