TypeScript 关于部分类型、条件类型和泛型的不兼容性令人难以理解,

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

TypeScript 版本: 3.9.0-dev.20200322
搜索词: partial, conditional types
代码

type SafePartial<T> = T extends {} ? Partial<T> : any;

interface QB<TRecord extends {}> {
  insert(record: SafePartial<TRecord>): void;
}

async function insert1<TRecord extends {}>(qb: QB<TRecord>, record: TRecord) {
  await qb.insert(record);
}

预期行为:

代码成功编译

实际行为:

对于 qb.insert(record) ,观察到以下错误:

Argument of type 'TRecord' is not assignable to parameter of type 'SafePartial<TRecord>'. Type '{}' is not assignable to type 'SafePartial<TRecord>'.

如果使用 Partial 而不是上面的 SafePartial,问题就会消失。
如果使用具体类型而不是泛型类型,问题也会消失:

interface User {
    id: string;
}

async function insert1(qb: QB<User>, record: User) {
  await qb.insert(record);
}

**Playground 链接:**Playground

j0pj023g

j0pj023g1#

与ts-essentials库的开放错误问题相似/相同:

export type Test<T> = T extends number // doesn't really matter what the condition is
  ? Partial<T>
  : Partial<T>; 

function conditionalPartialTestErrors<T>(): Test<T> {
  return {}; // error
}

function conditionalPartialTestCompiles<T>(): Partial<T> | Test<T> {
  return {}; // no error
}
z4iuyo4d

z4iuyo4d2#

我认为如果我们从方程中移除 Distribution,那么它将**"解决"**得更快,而不是在示例化步骤中。

type Test<T> = [T] extends number? Partial<T> : Partial<T>
function conditionalPartialTestErrors<T>(){
  return (state: Test<T> = {}) => {
  }
}
function conditionalPartialTestCompiles<T>(){
  return (state: Test<T> = {}) => {
  }
}

不过我不确定为什么一个会更快地解决,而另一个则必须推迟到示例化。

相关问题