首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过"is“运算符和条件类型缩小泛型类型范围

通过"is“运算符和条件类型缩小泛型类型范围
EN

Stack Overflow用户
提问于 2019-01-15 11:24:58
回答 1查看 159关注 0票数 4

我想使用is操作符将泛型类型限制为“原始类型的联合”或object类型。这两种方法都适用于我的用例。

以下代码段的适当解决方法是什么?( void>(value: () => () => void)" // All other values can be optionally wrapped with a getter, or passed as-is: new Foo(() => 1) // OK: Inferred as "Foo<1>(value: 1 | (() => 1))" new Foo(1) // OK: Inferred as "Foo<1>(value: 1 | (() => 1))" // Try narrowing to a primitive type: function testPrimitive(value: T) { if (isPrimitive(value)) { return new Foo(value) // ERROR: "Type 'T & string' is not assignable to type 'T & symbol extends Function ? never : T & symbol'." } } // Try narrowing to an object type: function testObject(value: T) { if (isObject(value)) { return new Foo(value) // ERROR: "Type 'T & object' is not assignable to type 'T & object extends Function ? never : T & object'." } } type Primitive = string | number | boolean | symbol | null | undefined const isPrimitive = (value: any): value is Primitive => !value || typeof value !== 'object' const isObject = (value: any): value is object => value && typeof value === 'object' )">playground

代码语言:javascript
复制
class Foo<T = any> {
    constructor(value: (() => T) | (T extends Function ? never : T)) {}
}

// Function values must be returned by a getter:
new Foo(() => () => {}) // OK: Inferred as "Foo<() => void>(value: () => () => void)"

// All other values can be optionally wrapped with a getter, or passed as-is:
new Foo(() => 1) // OK: Inferred as "Foo<1>(value: 1 | (() => 1))"
new Foo(1)       // OK: Inferred as "Foo<1>(value: 1 | (() => 1))"

// Try narrowing to a primitive type:
function testPrimitive<T>(value: T) {
    if (isPrimitive(value)) {
        return new Foo(value) // ERROR: "Type 'T & string' is not assignable to type 'T & symbol extends Function ? never : T & symbol'."
    }
}

// Try narrowing to an object type:
function testObject<T>(value: T) {
    if (isObject(value)) {
        return new Foo(value) // ERROR: "Type 'T & object' is not assignable to type 'T & object extends Function ? never : T & object'."
    }
}

type Primitive = string | number | boolean | symbol | null | undefined

const isPrimitive = (value: any): value is Primitive =>
    !value || typeof value !== 'object'

const isObject = (value: any): value is object =>
    value && typeof value === 'object'
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-16 05:54:42

让我们定义一下基础知识:

代码语言:javascript
复制
type Primitive = boolean | number | string | symbol | null | undefined;


class Foo<T> {
    constructor(value: T | (T extends Function ? never : T)) {}
}

new Foo(() => 1)
new Foo(1)

如果我们这样定义isPrimitiveisObject

代码语言:javascript
复制
declare function isPrimitive(argument: unknown): argument is Primitive;
declare function isObject<T extends object>(argument: T | Primitive): argument is T;

我们在调用点得到正确的类型推断:

代码语言:javascript
复制
function testPrimitive(argument: unknown) {
    if (isPrimitive(argument)) {
        return new Foo(argument);
    }
}

function testObject<T extends object>(argument: T | Primitive) {
    if (isObject(argument)) {
        return new Foo(argument);
    }
}

Playground

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

https://stackoverflow.com/questions/54192291

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档