Fix typing for 'Lifted<T>' to work better across versions of TS (#3658)

This commit is contained in:
CyrusNajmabadi 2019-12-13 11:18:19 -08:00 committed by GitHub
parent 5cb0731eba
commit 9151d48ee3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 129 additions and 5 deletions

View file

@ -1,6 +1,11 @@
CHANGELOG
=========
## Master (unreleased)
- Fix [SxS issue](https://github.com/pulumi/pulumi/issues/3652) introduced in 1.7.0 when assigning
`Output`s across different versions of the `@pulumi/pulumi` sdk
## 1.7.0 (2019-12-11)
- A Pulumi JavaScript/TypeScript program can now consist of a single exported top level function. i.e.:

View file

@ -47,9 +47,8 @@ istanbul_tests::
./node_modules/.bin/istanbul report text
sxs_tests::
# Intentionally disabled as PR https://github.com/pulumi/pulumi/pull/2609 breaks SxS
# will be renabled once that goes in.
# pushd tests/sxs && yarn && tsc && popd
pushd tests/sxs_ts_3.6 && yarn && tsc && popd
pushd tests/sxs_ts_latest && yarn && tsc && popd
test_fast:: sxs_tests istanbul_tests
$(GO_TEST_FAST) ${PROJECT_PKGS}

View file

@ -778,7 +778,12 @@ export type Lifted<T> =
// Specially handle 'string' since TS doesn't map the 'String.Length' property to it.
T extends string ? LiftedObject<String, NonFunctionPropertyNames<String>> :
T extends Array<infer U> ? LiftedArray<U> :
LiftedObject<T, NonFunctionPropertyNames<T>>;
T extends object ? LiftedObject<T, NonFunctionPropertyNames<T>> :
// fallback to lifting no properties. Note that `Lifted` is used in
// Output<T> = OutputInstance<T> & Lifted<T>
// so returning an empty object just means that we're adding nothing to Output<T>.
// This is needed for cases like `Output<any>`.
{};
// The set of property names in T that are *not* functions.
type NonFunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T];

View file

@ -55,3 +55,9 @@ declare let localUnshippedDerivedComponentResource: LocalUnshippedResourceExampl
latestShippedResource = localUnshippedDerivedComponentResource;
localUnshippedResource = latestShippedDerivedComponentResource;
declare let latestOutput: latestShipped.Output<any>;
declare let localOutput: localUnshipped.Output<any>;
latestOutput = localOutput;
localOutput = latestOutput;

View file

@ -0,0 +1,12 @@
{
"name": "sxs",
"version": "${VERSION}",
"license": "Apache-2.0",
"dependencies": {
"@pulumi/pulumi": "=1.6.0"
},
"devDependencies": {
"@types/node": "^8.0.0",
"typescript": "=3.6"
}
}

View file

@ -0,0 +1,13 @@
This test validates that changes we're making in @pulumi/pulumi will be side-by-side compatible with the 'latest' version of `@pulumi/pulumi` that has already shipped.
If a change is made that is not compatible, then the process should be:
1. Ensure that the change is absolutely what we want to make.
2. Disable running this test.
3. Commit the change and update the minor version of `@pulumi/pulumi` (i.e. from 0.17.x to 0.18.0).
4. Flow this change downstream, rev'ing the minor version of all downstream packages.
5. Re-enable the test. Because there is now a new 'latest' `@pulumi/pulumi`, this test should pass.
Step '3' indicates that we've made a breaking change, and that if 0.18 is pulled in from any package, that it must be pulled in from all packages.
Step '4' is necessary so that people can pick a set of packages that all agree on using this new `@pulumi/pulumi` version. While not necessary to rev the minor version of these packages, we still do so to make it clear that there is a significant change here, and that one should not move to it as readily as they would a patch update.

View file

@ -0,0 +1,63 @@
// tslint:disable:file-header
// See README.md for information on what to do if this test fails.
import * as latestShipped from "@pulumi/pulumi";
// Note: we reference 'bin' as we want to see the typescript types with all internal information
// stripped.
import * as localUnshipped from "../../bin";
declare let latestShippedResource: latestShipped.Resource;
declare let localUnshippedResource: localUnshipped.Resource;
declare let latestShippedComponentResourceOptions: latestShipped.ComponentResourceOptions;
declare let localUnshippedComponentResourceOptions: localUnshipped.ComponentResourceOptions;
declare let latestShippedCustomResourceOptions: latestShipped.CustomResourceOptions;
declare let localUnshippedCustomResourceOptions: localUnshipped.CustomResourceOptions;
latestShippedResource = localUnshippedResource;
localUnshippedResource = latestShippedResource;
latestShippedComponentResourceOptions = localUnshippedComponentResourceOptions;
localUnshippedComponentResourceOptions = latestShippedComponentResourceOptions;
latestShippedCustomResourceOptions = localUnshippedCustomResourceOptions;
localUnshippedCustomResourceOptions = latestShippedCustomResourceOptions;
// simulate a resource similar to AWSX where there are instance methods that take
// other resources and options.
class LatestShippedResourceExample1 extends latestShipped.ComponentResource {
constructor(name: string, props: any, opts: latestShipped.ComponentResourceOptions) {
super("", name, undefined, opts);
}
public createInstance(name: string, opts: latestShipped.ComponentResourceOptions): LatestShippedResourceExample1 {
throw new Error();
}
}
class LocalUnshippedResourceExample1 extends localUnshipped.ComponentResource {
constructor(name: string, props: any, opts: localUnshipped.ComponentResourceOptions) {
super("", name, undefined, opts);
}
public createInstance(name: string, opts: localUnshipped.ComponentResourceOptions): LocalUnshippedResourceExample1 {
throw new Error();
}
}
// make sure we can at least assign these to the Resource types from different versions.
declare let latestShippedDerivedComponentResource: LatestShippedResourceExample1;
declare let localUnshippedDerivedComponentResource: LocalUnshippedResourceExample1;
latestShippedResource = localUnshippedDerivedComponentResource;
localUnshippedResource = latestShippedDerivedComponentResource;
declare let latestOutput: latestShipped.Output<any>;
declare let localOutput: localUnshipped.Output<any>;
latestOutput = localOutput;
localOutput = latestOutput;

View file

@ -3,7 +3,7 @@
"version": "${VERSION}",
"license": "Apache-2.0",
"dependencies": {
"@pulumi/pulumi": "latest"
"@pulumi/pulumi": "=1.6.0"
},
"devDependencies": {
"@types/node": "^8.0.0",

View file

@ -0,0 +1,21 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2016",
"module": "commonjs",
"moduleResolution": "node",
"declaration": true,
"sourceMap": false,
"stripInternal": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.ts",
]
}