如何在TypeScript中定义排除指定类型B的类型A?
Great question! Let's break down why your initial approach didn't work, then walk through a solid solution that covers all possible non-string types.
Why Exclude<any, string> Fails
The core issue with type A = Exclude<any, string> is that any is TypeScript's top-level type—it’s compatible with every other type, including string. When you use Exclude<any, string>, TypeScript can’t narrow it down to non-string types because any effectively bypasses strict type checks. That’s why const a: A = 'monkey' still compiles without errors, even though you wanted it to fail.
Solution: Cover All Non-String Type Categories
While you can’t list every possible custom type explicitly, TypeScript’s type system has a finite set of core categories. We can combine these to create a type that includes everything except string:
// Define a type that covers all non-string categories type AllNonStringTypes = | Exclude<keyof any, string> // Covers number and symbol (keyof any = string | number | symbol) | boolean | null | undefined | object; // Covers all objects, arrays, functions, custom types, etc. type A = AllNonStringTypes;
Test the Type
Let’s verify it behaves as expected:
// ❌ Error: Type 'string' is not assignable to type 'AllNonStringTypes' const invalid: A = 'monkey'; // ✅ All these assignments are valid const validNumber: A = 42; const validBoolean: A = true; const validObject: A = { name: 'TypeScript' }; const validArray: A = [1, 2, 3]; const validFunction: A = () => 'hello'; const validNull: A = null; const validUndefined: A = undefined; const validSymbol: A = Symbol('unique-id');
Alternative: Generic Conditional Type
If you want a more flexible approach that enforces non-string checks for specific values, use a generic conditional type. This rejects strings at the point of assignment:
type NotString<T> = T extends string ? never : T; // ❌ Error: Type 'string' is not assignable to type 'never' const invalid: NotString<string> = 'monkey'; // ✅ Valid assignment const valid: NotString<number> = 42;
This is ideal if you don’t need a global non-string type and want to enforce constraints for individual variables.
内容的提问来源于stack exchange,提问作者Marthinus Engelbrecht

