如何在TypeScript中定义排除`any`的类型约束?@thisisagile/easy库Get类型优化问询
Great question! Let's tackle both parts of your query clearly:
1. Is there a TypeScript type that allows any type except any?
TypeScript doesn't have a built-in type for this, but we can easily create a type checker to detect whether a given type is any, then use that to exclude it from our type definitions.
The key insight here is leveraging TypeScript's special handling of any: when you intersect any with any other type, the result is still any. We can use this quirk to build our IsAny utility:
// Checks if a type T is exactly `any` type IsAny<T> = 0 extends (1 & T) ? true : false;
How this works:
- For
T = any:1 & anyevaluates toany, and0 extends anyreturnstrue(sinceanyis compatible with all types). - For any other type
T(likestring,number,unknown, etc.):1 & Tevaluates to a type that0does not extend, so the result isfalse.
2. Implementing a Get type that fixes your any edge case
With our IsAny checker, we can modify your existing Get type to behave exactly as you described: when T is any, we only allow the function variant; otherwise, we allow both the value and function variants.
First, let's confirm the Func type (matching your library's definition):
type Func<T, Args = unknown> = (...args: Args[]) => T;
Now, the improved Get type:
type Get<T = unknown, Args = unknown> = IsAny<T> extends true ? Func<T, Args> // Only allow function when T is any : T | Func<T, Args>; // Allow both value and function otherwise
Why this fixes your issue
In your original Get type, Get<any> resolved to any | Func<any, Args>. Since any absorbs all other types in a union, the entire type became any—this is why the compiler couldn't distinguish between a raw value and a function returning any.
With the modified type, Get<any> strictly resolves to Func<any, Args>, so the compiler will enforce that it's a function, and your Get() evaluation function will behave as expected.
Example usage
// Valid: T is string, can be value or function const stringValue: Get<string> = "hello world"; const stringFunc: Get<string> = () => "hello world"; // Valid: T is any, must be a function const anyFunc: Get<any> = () => "some any value"; // Invalid: T is any, cannot be a raw value (compiler error) const invalidAnyValue: Get<any> = "some any value";
This implementation should resolve the unexpected behavior you saw in edge cases involving any.
内容的提问来源于stack exchange,提问作者aahoogendoorn

