Typescript使用`typeof`方法连接原始泛型类型返回派生类型。

huangapple go评论63阅读模式
英文:

Typescript connect primitive generic type with typeof method returns derived type

问题

以下是翻译好的部分:

我有一个带有值的类。该值可能是字符串或数字类型。根据值的类型,我想将不同的值解析为相同的类型。
因此,如果值是字符串类型,我想将给定的值解析为字符串。

这段代码可以工作,但我的类型定义可能有问题。是否有一种方式可以让编译器显示typeOfValue的类型为"string"?

以下是我的当前解决方案。我知道在typeOfValue方法中存在类型定义的问题:

class MyClass<T extends string | number> {
    public constructor(private value: T) {
    }
    
    public typeOfValue(): `${T}` {
        return typeof this.value as `${T}`;
    }
}

const foo = new MyClass('foo');
// 我希望“theType”的类型为'string',但它的类型为'foo'
const theType = foo.typeOfValue();
英文:

I have a class with a value. The value might be of type string or number. Depending on the type of the value, I want to parse a different value to the same type.
So if value is of type string. I want to parse a given value to string.

The code works, but my typings are wrong. Is there a way that the compiler shows that typeOfValue is "string"?

Here is my current solution. I know that there is an issue with my typing in the typeOfValue method:

class MyClass&lt;T extends string | number&gt; {
    public constructor(private value: T) {
    }
    
    public typeOfValue(): `${T}` {
        return typeof this.value as `${T}`;
    }
}

const foo = new MyClass(&#39;foo&#39;);
// I want &quot;theType&quot; to be of type &#39;string&#39; but it is of type &#39;foo&#39;
const theType = foo.typeOfValue();

I understand that T is 'foo' because the type 'foo' extends the type 'string'. So typescript is setting T to the type 'foo'. But at this point I want the base type 'string'.

答案1

得分: 1

如果您有一个类型来模仿 `typeof` 操作符:

```ts
type TypeOf<T> =
    T extends Function ? "function" :
    T extends object | null ? "object" :
    T extends string ? "string" :
    T extends number ? "number" :
    T extends boolean ? "boolean" :
    T extends undefined ? "undefined" :
    T extends symbol ? "symbol" :
    T extends bigint ? "bigint" :
    never;

然后,您只需断言返回类型为 TypeOf<T>

class MyClass<T extends string | number> {
    public constructor(private value: T) {
    }
    
    public typeOfValue() {
        return typeof this.value as TypeOf<T>;
    }
}

并且它将按预期工作:

const foo = new MyClass('foo');

const theType = foo.typeOfValue();
//    ^? "string"

Playground


<details>
<summary>英文:</summary>

If you have a type to mimic the `typeof` operator:

```ts
type TypeOf&lt;T&gt; =
    T extends Function ? &quot;function&quot; :
    T extends object | null ? &quot;object&quot; :
    T extends string ? &quot;string&quot; :
    T extends number ? &quot;number&quot; :
    T extends boolean ? &quot;boolean&quot; :
    T extends undefined ? &quot;undefined&quot; :
    T extends symbol ? &quot;symbol&quot; :
    T extends bigint ? &quot;bigint&quot; :
    never;

then you can just assert that the return type is TypeOf&lt;T&gt;

class MyClass&lt;T extends string | number&gt; {
    public constructor(private value: T) {
    }
    
    public typeOfValue() {
        return typeof this.value as TypeOf&lt;T&gt;;
    }
}

and it'll work as expected:

const foo = new MyClass(&#39;foo&#39;);

const theType = foo.typeOfValue();
//    ^? &quot;string&quot;

Playground

huangapple
  • 本文由 发表于 2023年2月24日 00:19:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75547515.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定