简体   繁体   English

Typescript 泛型不适用于 Readonly

[英]Typescript generics does not work with Readonly

Let's have the following simplified example in TypeScript:让我们在 TypeScript 中使用以下简化示例:

type Foo = { name: string } | undefined

function fooWorks<T extends Foo>(input: T) {
    return input?.name // ok
}

function fooErrors<T extends Foo>(input: Readonly<T>) {
    return input?.name // error
}

Why fooWorks works, but fooErrors does not?为什么fooWorks有效,而fooErrors无效?

It gives the following error:它给出了以下错误:

Property 'name' does not exist on type NonNullable .属性“名称”在类型NonNullable上不存在。

The problem is, that the TypeScript compiler does not understand the subtle type narrowing here and throws a compile-time error as stated here (though, I am not 100% sure about how helpful this blog post is for you).问题是,该打字稿编译器不明白其中的奥妙型这里收窄,并抛出作为一个说明编译时错误在这里(虽然我不是100%地肯定这个博客帖子是如何帮助别人是你)。

Removing undefined from Foo works:Foo删除undefined有效:

type Foo = { name: string }

function fooWorks<T extends Foo>(input: T) {
    return input?.name
}

function fooErrors<T extends Foo>(input: Readonly<T>) {
    return input?.name
}

Or you can add the NonNullable type excluding null and undefined from T , which results in input being { name: string } :或者,您可以添加从T排除nullundefinedNonNullable类型,这会导致input{ name: string }

type Foo = { name: string } | undefined

function fooWorks<T extends Foo>(input: T) {
    return input?.name
}

function fooErrors<T extends Foo>(input: Readonly<NonNullable<T>>) {
  return input.name
}

The following will preserve the Readonly type and undefined as desired:以下将根据需要保留Readonly类型和undefined

function fooErrors<T extends Readonly<Foo>>(input: T) {
    return input?.name // works
}

Note: we set Readonly in the generic constraint and don't wrap it around the parameter type.注意:我们在泛型约束中设置了Readonly并且不将其包装在参数类型周围。

The reason, why fooErrors<T extends Foo>(input: Readonly<T>) causes issues is: TypeScript does not process unresolved generic type parameters (like T ) further. fooErrors<T extends Foo>(input: Readonly<T>)导致问题的原因是:TypeScript 不会进一步处理未解析的泛型类型参数(如T )。 Readonly essentially is a mapped type . Readonly本质上是一种映射类型 So in the function body, input has type { readonly [P in keyof T]: T[P]; }所以在函数体中, input类型为{ readonly [P in keyof T]: T[P]; } { readonly [P in keyof T]: T[P]; } , which unfortunately is not assignable back to T and its constraint Foo . { readonly [P in keyof T]: T[P]; } ,不幸的是不能分配回T及其约束Foo From the compiler's perspective property name on the parameter cannot be found anymore.从编译器的角度来看,无法再找到参数上的属性name

Playground code 游乐场代码

This seems to be a limitation of type aliases.这似乎是类型别名的限制。

interface Foo  { name: string }

function fooWorks<T extends Foo>(input?: T) {
    return input?.name // ok
}




function fooErrors<T extends Foo>(input?: Readonly<T>) {
    return input?.name // error
}

Behaves as expected.行为符合预期。

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

相关问题 Typescript“+”运算符如何与泛型和函数一起使用? - How does Typescript "+" operator work with generics and functions? Typescript 是如何推断出 Generics 的,为什么它在一种情况下不起作用? - How does Typescript infer Generics and why does it not work in one case? 带有 Class 的 Typescript 泛型不起作用或我做错了什么? - Typescript generics with Class does not work or what i am doing wrong? Typescript:缩小映射类型不适用于 generics - Typescript: Narrowing down mapped types does not work with generics 为什么 Typescript Union + Mapped Types 在有和没有泛型的情况下工作方式不同 - Why does Typescript Union + Mapped Types work differently with and without Generics 是什么 <this> 在TypeScript泛型中意味着什么? - What does <this> mean in TypeScript generics? 为什么数组“扩展”TypeScript 中的只读数组? - Why does an array 'extend' a readonly array in TypeScript? WebStorm不支持​​TypeScript的“枚举”或“只读” - WebStorm does not support `enum` or `readonly` for TypeScript 类型推断如何与 TypeScript 中的联合类型(+条件类型和泛型)一起使用? - How does type inference work with union types (+conditional types and generics) in TypeScript? 打字稿:无法让泛型与扩展一起使用 - Typescript: can't get generics to work with extends
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM