typescript - Distinguir entre objetos comuns e tipos de classe
Como posso distinguir um tipo de objeto simples de um tipo de classe?
class Foo {
constructor(public a: number) {}
}
declare let obj: {a: number}
declare let inst: Foo
// Either one would be fine.
type IsPlainObject<T> = ???
type IsClassType<T> = ???
Isso é necessário se você quiser usar "tipos mapeados" em objetos simples, mas nunca em tipos de classe.
edição: Os tipos de classe parecem ser idênticos às interfaces em muitos (na maioria? todos?) casos:
class Foo { a?: number }
class Bar { a?: number }
type A = Foo extends Bar ? 1 : 0 // => 1
type B = Bar extends Foo ? 1 : 0 // => 1
type Obj = { a?: number }
type C = Foo extends Obj ? 1 : 0 // => 1
type D = Obj extends Foo ? 1 : 0 // => 1
Link do playground
Questões relevantes
- https://github.com/Microsoft/TypeScript/issues/29063
- https://github.com/Microsoft/TypeScript/issues/5303#issuecomment-148894708
Resposta #1
Isso parece funcionar para mim:
type PlainObject<T> = T extends Record<keyof T, T[keyof T]> ? T : never;
