Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TypeScript-仅允许类型、文字和实例的类型约束_Typescript - Fatal编程技术网

TypeScript-仅允许类型、文字和实例的类型约束

TypeScript-仅允许类型、文字和实例的类型约束,typescript,Typescript,由于TypeScript的主动类型擦除,即类型注释、接口、类型和泛型类型参数都被编译器擦除,因此很难对某些类型约束建模。下面是我尝试建模的示例,以及我迄今为止成功实现的示例 参数必须是类型本身,而不是类型的实例或文本 这可以通过引入类型来解决,如下所示 type Type<T = any> = { new(...args: any[]): T; readonly prototype: T; readonly name: string; } 参数必须是实例或

由于TypeScript的主动类型擦除,即类型注释、接口、类型和泛型类型参数都被编译器擦除,因此很难对某些类型约束建模。下面是我尝试建模的示例,以及我迄今为止成功实现的示例

参数必须是类型本身,而不是类型的实例或文本

这可以通过引入
类型
来解决,如下所示

type Type<T = any> = {
    new(...args: any[]): T;
    readonly prototype: T;
    readonly name: string;
}

参数必须是实例或文字,而不是类型本身

这不是那么琐碎,到目前为止我还没能解决这个问题。给定以下函数定义

function fn(p: String) { ... }

fn("") // okay - it's a String literal
fn(new String()) // okay - it's a String instance
fn(String) // not okay - it's the String type
这很好,但当您想允许任何文字或实例,但不允许任何类型时,它就会中断

function fn(p: Object) { ... }

fn("") // okay - it's a String literal
fn(123) // okay - it's a Number literal
fn(new String()) // okay - it's a String instance
fn(String) // okay, BUT should be disallowed because it's the String type.
function fn(p: InstanceOrLiteral) { ... }

fn("") // okay - it's a String literal
fn(new String()) // okay - it's a String instance
fn(123) // okay - it's a Number literal
fn(String) // not okay - it's the String type
fn(Object) // not okay - it's the Object type
fn(Number) // not okay - it's the Number type
我不确定第二个问题是否可以解决,但是我想要与
类型一致的东西,但正好相反;例如

type InstanceOrLiteral<T = any> = {
    // what goes here?
}

function fn(p: InstanceOrLiteral<String>) { ... }

fn("") // okay - it's a String literal
fn(new String()) // okay - it's a String instance
fn(123) // not okay - it's a Number literal
fn(String) // not okay - it's the String type
后者可能吗

fn(String)//好的,但是应该被禁止,因为它是字符串 类型

不,它的
StringConstructor
类型。至少typescript和intellisense是这么说的

这对你有用吗

功能fn(p:K){
}

您的第一个问题可以通过使用条件类型来解决

type InstanceOrLiteral<T, WhatInstancesAreDisallowed = unknown> = 
    T extends { new(): WhatInstancesAreDisallowed } ? never : T
你的第二期需要一些技巧。您不能简单地将条件类型中的
T
设置为可选,并默认设置为
unknown
(=union of all type=>将始终匹配条件类型)或
any
(=禁用键入=>将导致条件类型的两个选项合并
never | T
,其解析为仅
T
=>因此也不符合您的要求)。相反,您必须推断函数调用的给定类型,并将其传递到
InstanceOrLiteral
类型。这样,条件类型可以与实际给定类型一起工作

function fn2<T>(p: T & InstanceOrLiteral<T>) { }

fn2("") // okay - it's a String literal
fn2(new String()) // okay - it's a String instance
fn2(123) // okay - it's a Number literal
fn2(String) // not okay - it's the String type
fn2(Object) // not okay - it's the Object type
fn2(Number) // not okay - it's the Number type
函数fn2(p:T&InstanceOrLiteral){
fn2(“”//好的-它是一个字符串文本
fn2(new String())//好的-这是一个字符串实例
fn2(123)//好的-这是一个数字文字
fn2(字符串)//不正常-这是字符串类型
fn2(对象)//不正常-这是对象类型
fn2(数字)//不正常-这是数字类型

这将适用于字符串|数字文本和实例,但不适用于任何实例或文本。本质上,约束应该是
类型的完全反转,所以这就像说,除了类型之外的任何内容。因此,您的示例需要类似于
函数fn(p:K){…}
这很有效。有没有办法禁止
InstanceOrLiteral
,因为它仍然允许类型?(在配置中不使用“no any”)@MatthewLayton遗憾的是,使用这种方法,条件类型需要特定给定参数的类型信息。我想不出任何其他方法。好的,dokey。这仍然是一个很好的解决方案,因此在此基础上,我接受!
type InstanceOrLiteral<T, WhatInstancesAreDisallowed = unknown> = 
    T extends { new(): WhatInstancesAreDisallowed } ? never : T
function fn(p: InstanceOrLiteral<String>) {}

fn("") // okay - it's a String literal
fn(new String()) // okay - it's a String instance
fn(123) // not okay - it's a Number literal
fn(String) // not okay - it's the String type
function fn2<T>(p: T & InstanceOrLiteral<T>) { }

fn2("") // okay - it's a String literal
fn2(new String()) // okay - it's a String instance
fn2(123) // okay - it's a Number literal
fn2(String) // not okay - it's the String type
fn2(Object) // not okay - it's the Object type
fn2(Number) // not okay - it's the Number type