简体   繁体   English

Typescript 不理解 T 在特定的复杂自定义类型中扩展接口

[英]Typescript not understanding that T extends interface in a specific complex custom type

So I'm using the Paths type I got from here , full disclosure, I don't fully understand how it's built and it will probably assist me in understanding the problem, I'll have my implementation of it at the bottom.所以我使用的是我从这里得到的Paths类型,完全公开,我不完全理解它是如何构建的,它可能会帮助我理解问题,我将在底部实现它。 In summary if I have the interface:总之,如果我有接口:

interface Person {
  name: string,
  contacts: {
    email: string,
    phone: string,
  }
}

Then Paths<Person> would result in union of literal types:然后Paths<Person>将导致文字类型的联合:

'name' | 'contacts' | 'contacts.email' | 'contacts.phone'

But when trying to use it with a generic that extends some type, I'm running into weird troubles.但是当尝试将它与扩展某种类型的泛型一起使用时,我遇到了奇怪的麻烦。

function foo<T extends Person> {
  let personParamGood: Paths<Person>;
  personParamGood = 'name' // great, works.
  
  let personParamBad: Paths<T>
  personParamBad = 'name' // typescript screams at me
  
}

The type error I get says我得到的类型错误说

error TS2322: Type '"name"' is not assignable to type 'T extends object ? { [K in keyof T]-?: K extends string | number ? `${K}` | Join<K, T[K] extends object ? { [K in keyof T[K]]-?: K extends string | number ? `${K}` | Join<K, never> : never; }[keyof T[K]] : ""> : never; }[keyof T] : ""'.

I don't get why, shouldn't T basically be Person ?我不明白为什么, T基本上不应该是Person

It does work on a simple type:它确实适用于简单的类型:

function foo<T extends Person> {
  let personParamGood: keyof Person;
  personParamGood = 'name' // great, works.
  
  let personParamGoodToo: keyof T
  personParamGoodToo = 'name' // great, works.
  
}

My implementation of Paths :我的Paths实现:

type Prev = [never, 0, 1, 2, 3, 5, 6, 7, 8, ...0[]];

type Join<K, P> = K extends string | number
  ? P extends string | number
    ? `${K}${'' extends P ? '' : '.'}${P}`
    : never
  : never;

export type Paths<T, D extends number = 10> = [D] extends [never]
  ? never
  : T extends object
  ? {
      [K in keyof T]-?: K extends string | number
        ? `${K}` | Join<K, Paths<T[K], Prev[D]>>
        : never;
    }[keyof T]
  : '';

That's because T will never resolve inside the function implementation as it can be anything.这是因为T永远不会function 实现中解析,因为它可以是任何东西。 You added an extends Person constraint on it but it can still be anything that extends Person .您在其上添加了extends Person约束,但它仍然可以是扩展Person的任何内容。 The actual T type is only known outside the function.实际的T型仅在 function 之外已知。

Notice how this code works when you hover the person variable:请注意当您 hover person变量时此代码如何工作:

interface Person {
  name: string,
  contacts: {
    email: string,
    phone: string,
  }
}

interface ExtendedPerson extends Person {
  address: string;
}

declare function foo<T extends Person>(): Paths<T>;

const person = foo<ExtendedPerson>();

But you'll never be able to make T (and thus Paths<T> ) resolve to an actual type inside the function implementation, that's how generics work in TypeScript and any other language.但是您将永远无法使T (因此Paths<T> )解析为 function 实现中的实际类型,这就是 generics 在 Z558B544CF685F39D34E4903E3 中的工作方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 typescript 中扩展泛型 T 的接口 - Extends interface of generic type T in typescript Typescript:使用特定的扩展接口来满足通用“扩展”类型参数? - Typescript: use specific extended interface to satisfy generic “extends” type argument? 了解TypeScript<t extends any[]></t> - Understanding TypeScript <T extends any[]> Typescript:扩展 JSON 类型的接口 - Typescript: interface that extends a JSON type 了解Typescript中的复杂类型声明 - Understanding complex type declaration in Typescript TypeScript争论一个接口与通用类型T不兼容,尽管T扩展了该接口 - TypeScript arguing that an interface is not compatible with generic type T, although T extends that interface Typescript - 将变量声明为扩展接口的类型 - Typescript - declaring a variable as a type which extends an interface 了解TypeScript中的特定继承类型 - Understanding specific type of inheritance in TypeScript TypeScript:如何使用属性扩展从其他接口检索的类型的接口 - TypeScript: interface how to extends a type that retrieved from other interface with a property 为什么我不能使用Typescript扩展自定义界面的HTMLElement类型? - Why can't I extends HTMLElement type for my customize interface using typescript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM