最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

typescript - How to narrow the object type by excluding specific class instances? - Stack Overflow

programmeradmin2浏览0评论

I want (for example) to forbid Date instances when calling a function that accepts objects:

type ExcludeDate<T> = T extends Date ? never : T

function f<T extends object>(arg: T & ExcludeDate<T>) {
}

f(new Date()) // Error: Argument of type 'Date' is not assignable to parameter of type 'never'.(2345)

Is there any simpler way to achieve the same result?

I'm looking for something like this (which doesn't work of course):

function f<T extends Exclude<object, Date>>(arg: T) {
}

I want (for example) to forbid Date instances when calling a function that accepts objects:

type ExcludeDate<T> = T extends Date ? never : T

function f<T extends object>(arg: T & ExcludeDate<T>) {
}

f(new Date()) // Error: Argument of type 'Date' is not assignable to parameter of type 'never'.(2345)

Is there any simpler way to achieve the same result?

I'm looking for something like this (which doesn't work of course):

function f<T extends Exclude<object, Date>>(arg: T) {
}
Share Improve this question edited Nov 28, 2024 at 9:48 jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Nov 28, 2024 at 9:46 Franck WolffFranck Wolff 966 bronze badges 3
  • 1 This is not really possible, since a Date is an object. A call f<object>(new Date()) will always succeed at the type level. – Bergi Commented Nov 28, 2024 at 12:59
  • 1 TS doesn't have negated types as requested in ms/TS#4196. You could use generics like you're doing to try to catch Dates. Or you could approximate "not a Date" like "an object without a defined getFullYear property" as shown in this playground link. It's not perfect since it will possibly exclude non-Dates, but in practice things like this are good enough (who puts getFullYear in a random object?). Does that fully address the question? If so I'll write an answer or find a duplicate. If not, what's missing? – jcalz Commented Nov 28, 2024 at 23:55
  • @jcalz Thanks for your reply and the link to [github/microsoft/TypeScript/issues/4196](ms/TS#4196). I will use Alexander Nenashev suggestion, which seems to work just fine. – Franck Wolff Commented Nov 29, 2024 at 13:39
Add a comment  | 

1 Answer 1

Reset to default 1

You can pass the generic param to a generic conditional type. To break the circular reference, use a mapped type:

Playground

type NotType<T extends object, U extends object, M = {[K in keyof T]: T[K]}> = M extends object ? M extends U ? never : M : never;

function f<T extends NotType<T, Date>>(arg: T) {

}

f(new RegExp('')) // ok
f(1); // not an object
f(new Date) // error
发布评论

评论列表(0)

  1. 暂无评论