在打字稿中:是否可以检查类型预期类型是否不是某种类型?或者创建一个定义不应该存在的方法/道具的界面?
答案 0 :(得分:1)
在TypeScript编译器中,虽然最终可能会这样做,但仍无法做到这一点。
This issue on the TypeScript project似乎是跟踪此功能请求的主要内容;许多其他类似的问题与它有关。
始终可以在运行时进行这些检查。这可以通过标准检查/断言手动完成。我个人喜欢将JSONSchema用于非平凡的“除X
个案例之外的所有内容”或io-ts包,以构建这些类型的运行时验证程序。在TypeScript中,您还可以访问type guard函数,这些函数可用于执行这些验证。
编辑这可以用有限的,不是非常有用的方式实现。使用this article中Omit
类型的修改,可以使类型检查器拒绝某些,但不是所有违反类型。
例如,假设您想要“不的任何object
的类型具有属性c
或d
”。你可以这样表达这种类型:
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
type AnyTypeWithoutCorD<T> = Omit<T, keyof T & ( "c" | "d" )>
使用该类型,类型检查器拒绝以下内容:
type MyType = { a: number, b: number, c: number };
// Accepts a generic argument and a parameter; ensures the
// parameter can be constrained into the AnyTypeWithoutCorD type.
function funcGeneric<T>(arg: AnyTypeWithoutCorD<T>) {}
// Accepts a parameter of a known type MyType, constrained
// into the AnyTypeWithoutCorD type.
function func(arg: AnyTypeWithoutCorD<MyType>) {}
let foo: AnyTypeWithoutCorD<MyType> = { a: 1, b: 1, c: 2 } // Error: type not assignable
func({ a: 1, b: 1, c: 2 }) // Error: type not assignable
funcGeneric<MyType>({ a: 1, b: 1, c: 2 }) // Error: type not assignable
<强>限制:强>
MyType
)中的所有键。不允许使用索引属性签名;那些导致类型检查器接受Omit
个对象而不管它们的字段。例如,如果在上面的示例中将[x: string]: any
添加到MyType
的规范中,则typechecker会愉快地接受所有参数(& { [x: string]: any }
是等效的并且行为方式相同)。如果您正在对您不控制其输入类型的事物执行Omit
- 类型验证,则这意味着如果任何输入类型具有索引属性签名,则不会进行验证。Omit
类型构造函数提供全新值,或在类型检查中等效“早期”执行某些操作的情况。从先前的赋值或通过类型断言提供数据不会按预期执行Omit
验证。Omit
类型的通用函数或类型,并且在调用函数时没有显式声明通用,它将会没有正确推断,因此不会发生Omit
验证,因为您的类型不会通过。例如,下面没有任何工作(类型检查器都是接受):
let bar: MyType = { a: 1, b: 1, c: 2 }
func(bar)
func({ a: 1, b: 1, c: 2 } as MyType)
funcGeneric(bar)
funcGeneric({ a: 1, b: 1, c: 2 })
let ok: AnyTypeWithoutCorD<object> = { a: 1, b: 1, c: 2 }
let ok: AnyTypeWithoutCorD<{ c: number }> = { a: 1, b: 1, c: 2 }
let ok: AnyTypeWithoutCorD<MyType> = { a: 1, b: 1, c: 2 } as MyType
let ok: AnyTypeWithoutCorD<MyType> = bar as MyType
这是我第一次尝试实现/展示这一点,所以人们对TypeScript和自定义类型构造的了解可能会纠正我。拿一粒盐。
<强>结论:强>
Omit
解决方案不值得。
除非您控制所有输入类型到Omit
接收器,并保持纪律以保持这些输入类型不含索引属性签名,并确保每次向其中一个接收器提供任何内容时它实际上是拿起Omit
约束,这将弊大于利。
这是因为有时会正确验证您的类型,这会产生错误的安全感和难以调试,看似不一致的行为。
问题的第一部分中链接的问题,如果完成,将为此用例提供更加强大,可预测和文档化的解决方案。在此之前,请使用运行时检查。
答案 1 :(得分:0)
禁止特定属性
使用never
类型告诉TypeScript对象上不应该存在属性。
interface Nameless extends Object {
name?: never;
}
用法:
declare function foo<T extends Nameless>(argument: T): void;
foo(document); // OK
foo(1); // OK
foo({ name: 'Bob' }); // Error
否定对象类型
使用Subtract
助手:
type Subtract<T, U> = T & Exclude<T, U>
用法:
declare function process<T>(argument: Subtract<T, Window>): void;
process(1) // OK
process({}) // OK
process(window) // Error
否定文字
再次使用Subtract
助手:
type Subtract<T, U> = T & Exclude<T, U>
用法:
type Insult =
| 'You silly sod!'
| 'You son of a motherless goat!';
declare function greet<T extends string>(greeting: Subtract<T, Insult>): void;
greet('Hello, good sir!'); // OK
greet('You silly sod!'); // Error!
答案 2 :(得分:-1)
在打字稿中:是否可以检查预期类型是否属于某种类型?
我怀疑你要找的是运行时类型。 TypeScript无法实现此目的,因为在JavaScript中没有标准化方式来执行此操作。
如果您只是寻找简单的类型防护,他们可以正常工作,例如
function foo(bar: string | number){
if (typeof bar !== 'string') {
// TypeScript knows its a number!
return bar.toPrecision(3);
}
}
键入警卫:https://basarat.gitbooks.io/typescript/content/docs/types/typeGuard.html