Skip to content

Instantly share code, notes, and snippets.

@Snugug
Last active June 20, 2018 15:02
Show Gist options
  • Save Snugug/72a6181e6b641d9e32df126135c0ae0c to your computer and use it in GitHub Desktop.
Save Snugug/72a6181e6b641d9e32df126135c0ae0c to your computer and use it in GitHub Desktop.
Need a way to type provider:SOMETHING so I can `new` its children
import { validate, IsInt, IsEmail, IsIn, IsNotEmpty } from 'class-validator';
import { Provider } from './provider';
export class InstanceConfig {
[key:string]: number | string;
@IsEmail()
@IsNotEmpty()
email: string;
@IsInt()
@IsNotEmpty()
duration: number;
}
export class InstanceInstance {
[key:string]: number | string | boolean;
@IsNotEmpty()
template: string;
@IsNotEmpty()
@IsIn(['emea', 'us-central', 'apac', 'aus-sydney'])
region: string;
@IsNotEmpty()
@IsIn(['default', 'on', 'off'])
internetAccess: string;
@IsNotEmpty()
smartrdp: boolean;
@IsNotEmpty()
@IsInt()
idleRuntimeLimit: number;
@IsNotEmpty()
@IsIn(['shutdown', 'off', 'suspend'])
idleRuntimeType: string;
@IsNotEmpty()
@IsInt()
totalRuntimeLimit: number;
}
export class InstanceProvider implements Provider<InstanceConfig, InstanceInstance> {
Config: new() => InstanceConfig;
Instance: new() => InstanceInstance;
}
export interface Provider<ProviderConfig, ProviderInstance> {
Config: new () => ProviderConfig;
Instance: new () => ProviderInstance;
}
import { InstanceProvider, InstanceConfig, InstanceInstance } from './skytap';
import { Provider } from './provider';
import { validate } from 'class-validator';
async function foo<ProviderConfig, ProviderInstance>(provider: Provider<ProviderConfig, ProviderInstance>) {
const config = new provider.Config();
config.email = 'foogmail.com';
config.duration = 10;
let errs = await validate(config, {whitelist: true});
console.log(errs);
}
foo<InstanceConfig, InstanceInstance>(new InstanceProvider());
@Snugug
Copy link
Author

Snugug commented Jun 20, 2018

Thanks @chriseppstein, I'm very close, but I'm missing something and I don't quite understand what's missing. With the above (updated) code, I get the following compile errors:

Property 'email' does not exist on type 'ProviderConfig'.
Property 'duration' does not exist on type 'ProviderConfig'.

I seem to be passing everything through properly, and the type validation is now working as I expect, but the actual InstanceConfig class doesn't appear to be used for validation, so it won't let me set the properties as I expect I should be able to.

Thoughts on this last bit? Thanks!

@Snugug
Copy link
Author

Snugug commented Jun 20, 2018

I think I've narrowed it down to https://gist.github.com/Snugug/72a6181e6b641d9e32df126135c0ae0c#file-use-js-L5, specifically that even though I believe I'm passing the types in properly for the generic, it's not actually picking up the structure inside the function. I can confirm that this in general works because if I use InstanceProvider outside of the function call it all works as expected

While that doesn't work, InstanceProvider.Config is not a constructor so I can't new it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment