-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Keyof includes class methods #18133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
|
There is a workaround/hacky way to filter methods out using type level programming. The following works with the latest nightly build of the compiler. type Bool = 'true' | 'false'
type Not<X extends Bool> = {
true: 'false',
false: 'true'
}[X]
type HaveIntersection<S1 extends string, S2 extends string> = (
{ [K in S1]: 'true' } &
{ [key: string]: 'false' }
)[S2]
type IsNeverWorker<S extends string> = (
{ [K in S]: 'false' } &
{ [key: string]: 'true' }
)[S]
// Worker needed because of https://github.com/Microsoft/TypeScript/issues/18118
type IsNever<T extends string> = Not<HaveIntersection<IsNeverWorker<T>, 'false'>>
type IsFunction<T> = IsNever<keyof T>
type NonFunctionProps<T> = {
[K in keyof T]: {
'false': K,
'true': never
}[IsFunction<T[K]>]
}[keyof T]
class Model {
public id: string
public createdAt: Date
public lastModified: Date
version: number
private transient: Object
save(): Promise<this> {
return null!;
}
}
enum Type {
string,
number,
date
// ...
}
type Schema<T extends Model> = { [P in NonFunctionProps<T>]: Type }
let schema: Schema<Model> = {
id: Type.string, // <-- try commenting me out for a type error
createdAt: Type.date,
lastModified: Type.date,
version: Type.number
} |
@gcnew it is interesting why var x: NonFunctionProps<Model>; produces |
Which compiler version are you using? I have type X = NonFunctionProps<Model>; // 'id' | 'createdAt' | 'lastModified' | 'version' |
@gcnew yes, you are right, I have tried it at 2.5.1 version, now I've updated master branch and it works, thanks! |
@RyanCavanaugh why is that? considering that Example:
hello is not a member of
after assigning hello to it, hello is an actual member of it, and javascript reflects that |
|
class Test {
hello() {
console.log('hello')
}
}
let it = new Test()
it.hello() // hello
console.log(Object.keys(it)) // []
console.log('hello' in it); // true
console.log(typeof it.hello); // function Who ever said that JavaScript was rational? This is one of the reasons why TypeScript is a structurally typed language. In most ways |
TypeScript Version: 2.4.2
Code
Expected behavior:
Expected behavior here is that keyof follows own enumerable types of class, and thus, schema is validly typed. Note, that a Partial is not an option since this example needs all properties to be defined in schema.
Actual behavior:
The text was updated successfully, but these errors were encountered: