gpt4 book ai didi

javascript - TypeScript - 如果扩展其他内容,则类泛型类型太窄,如果不扩展任何内容则不是

转载 作者:行者123 更新时间:2023-12-05 03:42:56 25 4
gpt4 key购买 nike

我有像 Item<T> 这样的类(class)和 StrictItem<T extends Something> .如果我像 Item('a') 一样初始化前者它将被视为 Item<string> , 而 StrictItem<'a'>将被视为 StrictItem<'a'> .

  1. 为什么对通用进行限制会导致这些差异?好像没什么关系。
  2. 有没有办法改变StrictItem定义,所以 StrictItem('a')将是 StrictItem<string> ,同时仍然保留对泛型的约束?

Playground

interface PlainObject<T> { [index: string ]: T}

type ItemValue =
boolean |
number |
string |
ItemValue[] |
{ [index: string ]: ItemValue } |
null;

class Item<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
public set(value: T) {
this.value = value;
}
}

// This one puts restrictions on the generic
class StrictItem<T extends ItemValue> extends Item<T> {
}

// 1. Why does the error seen in item2 does not occur here?
let item1 = new Item('a');
item1.set('b');
item1.set(0); // error

// 1. Can StrictItem definition be modified to implictly infer a more
// general type ('string') in this case (without using any type for T)?
// Or is explicitly defining the type of passed value the only way (see item3)?
let item2 = new StrictItem('a');
item2.set('b'); // error

let item3 = new StrictItem('a' as string);
item3.set('b');

最佳答案

Why does putting a constraint on the generic cause these differences? It doesn't seem to be related.

我相信当你这样做时<T>您告诉编译器,“只需使用通常会推断出的任何内容。在 let foo = 'bar' 中,foo 被推断为 string。没有额外的符号,这作为默认值是有意义的。

然而,<T extends ItemValue>说的有些不同。这告诉编译器“T 是一个扩展 ItemValue 的类型,这意味着它可能是一个更具体的子类型。”在这种情况下,它将尽可能推断出最具体的类型。

所以如果你约束一个泛型,你应该期望它是一个超特定类型。通常,这就是您想要的。


Is there a way to change the StrictItem definition, so StrictItem('a') would be StrictItem<string>, while still preserving the constraint on the generic?

据我所知没有。但这实际上通常不是问题。很难从您设计的示例中建议采取行动,但通常您实际上并没有将字符串文字硬编码为这样的类型。相反,数据可能来自其他一些数据源、函数或变量。

在这种情况下,您可以简单地向它传递一个类型为 string 的变量。它的工作方式与您预期的一样。

let item4Data = getSomeString() // returns string
let item4 = new StrictItem(item4Data) // StrictItem<string>

如果你真的只想传递一个文字,你总是可以在使用类型时显式地传递一个类型参数。这是类型安全的,因为会根据您提供的类型检查参数的类型。

let item5 = new StrictItem<string>('a')
item5.set('b') // works

let item6 = new StrictItem<string>(123) // type error

关于javascript - TypeScript - 如果扩展其他内容,则类泛型类型太窄,如果不扩展任何内容则不是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67070250/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com