Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么TypeScript在嵌套对象中不能推断泛型类型?

为什么TypeScript在嵌套对象中不能推断泛型类型?
EN

Stack Overflow用户
提问于 2018-09-13 14:57:51
回答 2查看 4.7K关注 0票数 8

我有一种TypeScript无法推断出的类型。

代码语言:javascript
运行
AI代码解释
复制
interface Foo<A> {
    [name: string] : {
        foo : A
    }
}

function makeFoo<A>(foo: Foo<A>) : Foo<A>{
    return foo
}

// Works fine when manually specifying the types
const manuallyTyped : Foo<string | number> = {
    a: {
        foo: '1'
    },
    b: {
        foo: 3
    }
}

// ERROR, Can't infer type as Foo<string | number>
makeFoo({
    a: {
        foo: '1'
    },
    b: {
        foo: 3
    }
})

最初,我使用了下面的类型,但我希望使对象对象本身的值。当索引签名是平坦的时,推理工作得很好。

代码语言:javascript
运行
AI代码解释
复制
interface FlatFoo<B> {
    [name: string] : B
}

function makeFlatFoo<B>(bar: FlatFoo<B>): FlatFoo<B>{
    return bar
}

// Correctly has type FlatFoo<string | number>
const inferred = makeBar({
    a: 'a',
    b: 2
})

是否有人对此有解释和/或建议?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-14 21:28:40

这是一个类似于this questionthis question的问题。当TypeScript为相同类型的参数(在第一个示例中,numberstring用于A)进行多个协变推理时,它尝试选择其中一个是其他参数的超级类型;它不会推断出一个联合,除非在特殊情况下,推理是相同原语类型的文字类型。如果TypeScript在其他情况下似乎推断出一个联合类型,那是因为其他一些语言特性起作用了。在makeFlatFoo中,该特性是对象文字类型的隐式索引签名生成,它将属性ab的类型(即string | number )的类型结合在一起。string | numberB相匹配,您可以得到Bstring | number的一个推论,一切都正常。但是,在makeFoo中,隐式索引签名的返回类型是Foo<string> | Foo<number>。当这与Foo<A>相匹配时,联合就会被分解,您将得到stringnumber对于A的两个不同的推论。

虽然以下基于您的答案的示例编译时没有错误:

代码语言:javascript
运行
AI代码解释
复制
function makeFoo<A, F extends Foo<A>>(foo: F) : F{
    return foo
}

const result = makeFoo({
    a: {
        foo: '1'
    },
    b: {
        foo: 3
    }
});

您将看到A{}result的类型是{ a: { foo: string; }; b: { foo: number; }; },所以还没有成功地将对象转换为Foo<T>类型。相反,可以使用类型参数FA来捕获隐式索引签名的返回类型,然后使用分布式条件类型提取foo属性的实际类型,如this answer中的那样。

代码语言:javascript
运行
AI代码解释
复制
interface FlatFoo<FA> { 
    [name: string]: FA;
}
type FooPropTypes<FA> = FA extends { foo: infer A } ? A : never;
function makeFoo<FA extends {foo: unknown}>(foo: FlatFoo<FA>) : Foo<FooPropTypes<FA>> {
    return <any>foo
}
票数 6
EN

Stack Overflow用户

发布于 2018-09-13 15:21:02

看起来您可以通过更新makeFoo来将整个输入捕获为泛型来修复这个问题。

代码语言:javascript
运行
AI代码解释
复制
function makeFoo<A, F extends Foo<A>>(foo: F) : F{
    return foo
}

这与我所期望的不完全一样,但结构类型的效果很好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52322803

复制
相关文章
Java 泛型中的类型推断
这样写,编译器报错: jshell> List<?> unknows = new ArrayList<?>() | Error: | unexpected type | required:
一个会写诗的程序员
2018/08/17
3K0
TypeScript-在泛型约束中使用类型参数
如上的代码在编译器当中是会报错的,报错的原因就是它不知道 obj[key] 返回的到底是不是 any 这个类型,这个错其实可以不用管,如果要想解决这个错误可以利用 interface 来解决,我可以先给出利用 interface 解决这个错误的代码:
杨不易呀
2023/09/28
2430
TypeScript-在泛型约束中使用类型参数
初探 TypeScript函数基本类型泛型接口类内置对象
前段时间有朋友和我推荐 TypeScript ,他说写起来特别爽,让我去试一试,那时候我还在那是啥高深莫测的东西。刚好那段时间忙,一直没有时间看。最近也很忙,还是抽时间来探一探 TypeScript ;简单说 ts 主要提供的是 dynamic type check,提供的 interface 接口这个功能在开发项目的时候会很有帮助。TypeScript是 JavaScript 的一个超集。他和 JavaScript 有着千丝万缕的关系。
sunseekers
2018/10/31
7.3K0
TypeScript - 泛型
从上面的信息概括为泛型是支持多种类型的变量,根据用户需求灵活的变动,达到复用的效果。 在实际开发中,函数是同样的逻辑,只是因为类型的不同,可能要再写一个函数,这样的问题很糟糕。正好泛型就可以用来解决这种问题。
WahFung
2020/08/22
1.2K0
TypeScript泛型
我们可以通过如上代码片段发现方法没有确切定义返回值类型,运行的数组每一项都可以是任意类型
HueiFeng
2020/04/10
6830
TypeScript泛型
在 TypeScript 中,泛型(Generics)是一种用于创建可重用的组件的强大工具。泛型允许在函数、类和接口中使用类型参数,使得这些组件能够适应多种数据类型,提高代码的灵活性和可重用性。
堕落飞鸟
2023/05/22
5120
TypeScript泛型
我们可以通过如上代码片段发现方法没有确切定义返回值类型,运行的数组每一项都可以是任意类型
HueiFeng
2020/04/09
7370
用泛型来实现编译时期的类型推断
第一章都是讲泛型的,距离上一篇Effective C#的随笔已经是很久以前的事情了。。。
_淡定_
2018/08/24
1.2K0
Typescript之泛型
泛型接口的使用 function add<T>(arg1: T, arg2: T): T { return arg1 + arg2; } // <T>(arg1:T,arg2:T)=>T add<number>(1, 2); add<string>('1', '2') // let addFunc: <T>(arg1: targ2: T) => T // let addFunc: { <T>(arg1: T, arg2: T): T } // interface GenAdder { <T>(a
lilugirl
2020/06/28
6200
TypeScript 函数泛型
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性
Leophen
2020/08/10
1.1K0
TypeScript 函数泛型
typescript入门-泛型
基础定义 function join<T>(list:T[]):string{ return list.join(',') } join<string>(['coco', 'jeck']) 泛型接口 interface join { <T>(args:T[]):string } interface Man<T>{ name:string race:T } 泛型类 class Man<T>{ name:string rece:T constructor(name:stri
copy_left
2021/06/11
6080
TypeScript泛型应用
泛型程序设计(generic programming)是程序设计语言的一种风格或范式。泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。
前端小鑫同学
2022/12/26
5010
TypeScript泛型应用
TypeScript中泛型及泛型函数、泛型类、泛型接口,泛型约束,一文读懂
 最近在学TypeScript,然后整理了一下关于TypeScript中泛型的一些笔记。
痴心阿文
2022/11/21
2.9K0
TypeScript-泛型
还是和之前一样的套路,利用一个需求来引出没有使用泛型的弊端,需求: 定义一个创建数组的方法, 可以创建出 指定长度 的数组, 并且可以用 任意指定的内容 填充这个数组:
杨不易呀
2023/09/28
1700
TypeScript-泛型
《现代Typescript高级教程》泛型和类型体操
泛型和类型体操(Type Gymnastics)是 TypeScript 中高级类型系统的重要组成部分。它们提供了强大的工具和技巧,用于处理复杂的类型操作和转换。
linwu
2023/07/27
4050
TypeScript 类型注解和类型推断
当不添加类型注解时,TypesScript 也能知道变量 a 是一个数字,这就是 TypeScript 的类型推断:
Leophen
2020/07/23
1.2K0
TypeScript 基本类型和泛型的使用
typescript 基础类型 下面只介绍一些区别于 JavaScript 的特殊类型 Tuple 元组 元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。比如,你可以定义一对值分别为 string 和 number 类型的元组。 // Declare a tuple type let x: [string, number]; // Initialize it x = ['hello', 10]; // OK // Initialize it incorrectly x = [10, 'h
西南_张家辉
2021/02/02
2.6K0
TypeScript-自动类型推断
如上的 let value = 123; TS 会自动推断为 let value: number = 123; 所以如上的 value 变量只能存储 number 类型的数据,如上是单个数据类型的推断,接下来在来看一个 联合类型 的推断:
杨不易呀
2023/09/28
2420
TypeScript-泛型约束
博主需求: 要求指定的泛型类型必须有 length 属性才可以指定该类型为泛型的类型:
杨不易呀
2023/09/28
2400
TypeScript-泛型约束
泛型_TypeScript笔记6
从类型上看,无论参数是什么类型,返回值的类型都与参数一致,借助重载机制,可以这样描述:
ayqy贾杰
2019/06/12
1.1K0

相似问题

推断typescript嵌套泛型类型

10

为什么不能推断嵌套泛型类型?

10

为什么TypeScript不能推断这个泛型类型?

112

TypeScript型泛型不能正确推断类型

11

TypeScript泛型类型推断

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文